Option型

プログラミング言語efn|特に関数型プログラミング言語において。と型理論において、Option型（Option type）またはMaybe型（Maybe type）は存在しない可能性のある値をカプセル化して表すlabel=多相型である。例えば、関数の戻り値が存在する場合と存在しない場合を表すためにこの型は使用される。この型は空多くの場合、NoneまたはNothingという名前。またはオリジナルのデータ型Aをカプセルした多くの場合、Just AまたはSome Aと書かれる。コンストラクタから構成されている。
関数型プログラミング以外において、全く異なるが関連する概念としてNullable型多くの場合、A?として表される。がオブジェクト指向プログラミングで一般的である。Option型とNullable型の主な違いは、Option型はネストすることができる例えば、Maybe (Maybe String) ≠ Maybe String。のに対して、Nullable型はこれに対応していないことである。

**理論的側面**
型理論において、Option型はのように記述することができる。これは与えられた値の組に対して、Option型はの有効な値の組に正確に1つの追加の値（空の値）を追加するという事実を表している。これはTagged unionを持つ言語において、Option型がカプセル化型とunit typeのタグ付き共用体として表現できるという事実によってプログラミングに反映されている。
カリー＝ハワード同型対応において、Option型は∨: x∨1=1の消滅法則に関連しているtitle=It is unclear how this is the case, and there are no links to external references that explain this.。
。
Option型もモナドであり、次のようになる:
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型のモナディックな性質は、失敗とエラーを効率的に追跡するのに役立つ。

**型名と定義**
それぞれのプログラミング言語において、Option型は様々な名前と定義がある。- Agdaでは、nothingとjust aという要素を持ち、Maybeという名前で定義されている。- Coqでは、として定義されている。- Elmでは、elmという名前でとして定義されている。- Haskellでは、haskellという名前でとして定義されている。- Idris (programming language)では、として定義されている。- OCamlでは、として定義されている。- Pythonでは、3.10以降でcode|2=python|1=typing.OptionalTまたはefn|型ヒントを介して。として示される。- Rustでは、として定義されている。- Scalaでは、code|2=scala|1=final case class Some+A(value: A)と1=case object Noneの型拡張によって、code|2=scala|1=sealed abstract class Option+Aとして定義されている。- Standard MLでは、として定義されている。- Swiftでは、として定義されているが、通常はT?として記述される。

**例**

**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: Optionint): 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) -> 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になることができ、次のようにアクセスできる:
コード例:
object Main {
def compute(opt: OptionInt): String =
opt.fold("No value")(x => s"The value is: $x")
def main(args: ArrayString): 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番目の例のようなモナディックアプローチである。このように、プログラムは例外またはエラーを生成することができない例えばNoneと等しいOption変数の値を取得しようとすることによって。ので安全である。従って、これは基本的に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 節が評価される。

**脚注**

**注釈**

**出典**

**関連項目**
 Result型- Tagged union- Nullable型- Null object pattern- 例外処理- パターンマッチング