Option型
プログラミング言語[注釈 1]と型理論において、Option型(英語: Option type)またはMaybe型(英語: Maybe type)は�…
この項目「Option型」は翻訳されたばかりのものです。不自然あるいは曖昧な表現などが含まれる可能性があり、このままでは読みづらいかもしれません。(原文:英語版 "Option type" 2022年6月10日 (金) 10:23 (UTC)) 修正、加筆に協力し、現在の表現をより自然な表現にして下さる方を求めています。ノートページや履歴も参照してください。(2022年6月) |
この記事には複数の問題があります。 |
プログラミング言語[注釈 1]と型理論において、Option型(英語: Option type)またはMaybe型(英語: Maybe type)は存在しない可能性のある値をカプセル化して表す多相型である。例えば、関数の戻り値が存在する場合と存在しない場合を表すためにこの型は使用される。この型は空[注釈 2]またはオリジナルのデータ型Aをカプセルした[注釈 3]コンストラクタから構成されている。
関数型プログラミング以外において、全く異なるが関連する概念としてNullable型[注釈 4]がオブジェクト指向プログラミングで一般的である。Option型とNullable型の主な違いは、Option型はネストすることができる[注釈 5]のに対して、Nullable型はこれに対応していない[注釈 6]ことである。
理論的側面
この節には複数の問題があります。 |
型理論において、Option型はのように記述することができる。これは与えられた値の組に対して、Option型はの有効な値の組に正確に1つの追加の値(空の値)を追加するという事実を表している。これはタグ付き共用体を持つ言語において、Option型がカプセル化型とUnit型のタグ付き共用体として表現できるという事実によってプログラミングに反映されている[1]。
カリー=ハワード同型対応において、Option型は∨: x∨1=1の消滅法則に関連している[どうやって?]。
Option型は1個または0個の要素を含むコレクションと見なすこともできる[独自研究?]。
return = Just -- Wraps the value into a maybe
Nothing >>= f = Nothing -- Fails if the previous monad fails
(Just x) >>= f = f x -- Succeeds when both monads succeed
Option型のモナディックな性質は、失敗とエラーを効率的に追跡するのに役立つ[3]。
型名と定義
それぞれのプログラミング言語において、Option型は様々な名前と定義がある。
- Agdaでは、
nothingとjust aという要素を持ち、Maybeという名前で定義されている。 - Coqでは、
Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.として定義されている。 - Elmでは、
Maybeという名前でtype Maybe a = Just a | Nothingとして定義されている[4]。 - Haskellでは、
Maybeという名前でdata Maybe a = Nothing | Just aとして定義されている。 - Idrisでは、
data Maybe a = Nothing | Just aとして定義されている。 - OCamlでは、
type 'a option = None | Some of 'aとして定義されている。 - Pythonでは、3.10以降で
typing.Optional[T]またはT | None[注釈 7]として示される。 - Rustでは、
enum Option<T> { None, Some(T) }として定義されている。 - Scalaでは、
final case class Some[+A](value: A)とcase object Noneの型拡張によって、sealed abstract class Option[+A]として定義されている。 - Standard MLでは、
datatype 'a option = NONE | SOME of 'aとして定義されている。 - Swiftでは、
enum Optional<T> { case none, some(T) }として定義されているが、通常はT?として記述される[5]。
例
F#
- コード例
let compute = Option.fold (fun _ x -> sprintf "The value is: %d" x) "No value" let full = Some 42 let empty = None compute full |> printfn "compute full -> %s" compute empty |> printfn "compute empty -> %s"
- 実行結果
compute full -> The value is: 42 compute empty -> No value
Haskell
- コード例
compute :: Maybe Int -> String compute = foldl (\_ x -> "The value is: " ++ show x) "No value" main :: IO () main = do let full = Just 42 let empty = Nothing putStrLn $ "compute full -> " ++ compute full putStrLn $ "compute empty -> " ++ compute empty
- 実行結果
compute full -> The value is: 42 compute empty -> No value
Nim
- コード例
import std/options proc compute(opt: Option[int]): string = opt.map(proc (x: int): string = "The value is: " & $x).get("No value") let full = some(42) empty = none(int) echo "compute(full) -> ", compute(full) echo "compute(empty) -> ", compute(empty)
- 実行結果
compute(full) -> The Value is: 42 compute(empty) -> No value
OCaml
OCamlはOptionをパラメータ化された要素型として実装している。Optionは次のように構築及び分解される:
- コード例
let compute = Option.fold ~none:"No value" ~some:(fun x -> "The value is: " ^ string_of_int x) let () = let full = Some 42 in let empty = None in print_endline ("compute full -> " ^ compute full); print_endline ("compute empty -> " ^ compute empty)
- 実行結果
compute full -> The value is: 42 compute empty -> No value
Rust
- コード例
fn compute(opt: Option<i32>) -> String { opt.map_or("No value".to_owned(), |x| format!("The value is: {}", x)) } fn main() { let full = Some(42); let empty = None; println!("compute(full) -> {}", compute(full)); println!("compute(empty) -> {}", compute(empty)); }
- 実行結果
compute(full) -> The value is: 42 compute(empty) -> No value
Scala
ScalaはOptionをパラメータ化された型として実装しているので、変数はOptionになることができ、次のようにアクセスできる[6]:
- コード例
object Main { def compute(opt: Option[Int]): String = opt.fold("No value")(x => s"The value is: $x") def main(args: Array[String]): Unit = { val full = Some(42) val empty = None println(s"compute(full) -> ${compute(full)}") println(s"compute(empty) -> ${compute(empty)}") } }
- 実行結果
compute(full) -> The value is: 42 compute(empty) -> No value
Optionの値を使用する方法は2つある。1つは、最良ではないが最初の例のようにパターンマッチングによる方法である。もう1つは、最良の方法である2番目の例のようなモナディックアプローチである。このように、プログラムは例外またはエラーを生成することができない[注釈 8]ので安全である。従って、これは基本的にnull値の型安全な代替手段として機能する。
Swift
- コード例
func compute(_ opt: Int?) -> String { return opt.map { "The value is: \($0)" } ?? "No value" } let full = 42 let empty: Int? = nil print("compute(full) -> \(compute(full))") print("compute(empty) -> \(compute(empty))")
- 実行結果
compute(full) -> The value is: 42 compute(empty) -> No value
Zig
- コード例
const std = @import("std"); const print = std.io.getStdOut().writer().print; const Compute = struct { value: ?i32, pub fn init(value: ?i32) Compute { return Compute{ .value = value }; } pub fn format( self: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: anytype, ) !void { _ = fmt; _ = options; if (self.value) |n| { return out_stream.print("The value is: {}", .{n}); } else { return out_stream.print("No value", .{}); } } }; pub fn main() !void { const full = Compute.init(42); const empty = Compute.init(null); try print("full -> {}\n", .{full}); try print("empty -> {}\n", .{empty}); }
- 実行結果
full -> The value is: 42 empty -> No value
- Zigでは、
?i32の様に型名の前に ? を追加するとOptional型となる。 if (opt) |n| {の様に if 文、あるいは while文でペイロード n をキャプチャーすることができ、null の場合 else 節が評価される。
脚注
注釈
出典
- ^ Milewski, Bartosz (2015年1月13日). “Simple Algebraic Data Types” (英語). Bartosz Milewski's Programming Cafe. 2019年8月18日時点のオリジナルよりアーカイブ。2019年8月18日閲覧。
- ^ “A Fistful of Monads - Learn You a Haskell for Great Good!”. www.learnyouahaskell.com. 2019年8月18日閲覧。
- ^ Hutton, Graham (2017年11月25日). “What is a Monad?”. Computerphile Youtube. 2021年12月20日時点のオリジナルよりアーカイブ。2019年8月18日閲覧。
- ^ “Maybe · An Introduction to Elm”. guide.elm-lang.org. 2022年6月11日閲覧。
- ^ “Apple Developer Documentation”. developer.apple.com. 2020年9月6日閲覧。
- ^ Martin Odersky; Lex Spoon; Bill Venners (2008). Programming in Scala. Artima Inc. pp. 282–284. ISBN 978-0-9815316-0-1 2011年9月6日閲覧。
関連項目
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.