プログラミング言語(特に関数型プログラミング言語)および型理論において、オプション型またはmay be 型は、オプション値のカプセル化を表す多態型です。たとえば、適用時に意味のある値を返す場合と返さない場合がある関数の戻り値の型として使用されます。これは、空のコンストラクタ(多くの場合None、またはと命名されるNothing)または元のデータ型をカプセル化するコンストラクタA(多くの場合Just A、またはと記述されるSome A)で構成されます。
関数型プログラミング以外では、オブジェクト指向プログラミングでよく使われる、独特だが関連のある概念が、 null 許容型( と表現されることが多い)と呼ばれますA?。オプション型と null 許容型の主な違いは、オプション型はネスト (例: Maybe (Maybe String)≠ Maybe String) をサポートするのに対し、null 許容型はサポートしない (例: String??= String?) ことです。
理論的側面
型理論では、これは次のように記述されることがあります。これは、 内の特定の値のセットに対して、オプション型が の有効な値のセットに正確に 1 つの追加値 (空の値) を追加するという事実を表しています。これは、プログラミングにおいて、タグ付き共用体を持つ言語では、オプション型はカプセル化された型のタグ付き共用体とユニット型として表現できるという事実に反映されています。[1]
カリー・ハワード対応では、オプションタイプは、∨: x∨1=1 の消滅法則と関連しています。 [どのように? ]
オプション型は、1 個または 0 個の要素を含むコレクションとして見ることもできます。 [独自の研究? ]
オプション型もモナドであり、次のようになります: [2]
return = Just -- 値をmaybeにラップします
Nothing >>= f = Nothing -- 前のモナドが失敗した場合は失敗します( Just x ) >>= f = f x -- 両方のモナドが成功した場合は成功します
オプション型のモナド的な性質は、失敗やエラーを効率的に追跡するのに役立ちます。[3]
例
アグダ
Agda では、オプション タイプはMaybeバリアントnothingとで名前が付けられます。
just a
ATSM
ATSでは、オプションタイプは次のように定義されます。
データ型 option_t0ype_bool_type ( a : t @ ype +, bool ) =
| Some ( a , true ) of a
| None ( a , false )
stadef option = option_t0ype_bool_type
typedef Option ( a : t @ ype ) = [ b : bool ] option ( a , b )
# "share/atspre_staload.hats"をインクルードします
fn show_value ( opt : Option int ): string =
case + opt of
| None () => "値なし"
| Some ( s ) => tostring_int s
main0 ()を実装します: void = let
val full = Some 42
and empty = None
in
println !( "show_value full → " , show_value full );
println !( "show_value empty → " , show_value empty );
end
show_value がいっぱい → 42
show_value が空 → 値なし
C++
C++17 以降、オプション型は標準ライブラリで として定義されています。
template<typename T> std::optional<T>
コック
Coq では、オプション型は として定義されます。
Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.
エルム
Elmではオプション型は次のように定義されます。[4]type Maybe a = Just a | Nothing
ファ#
F#ではオプション型は次のように定義されます。[5]type 'a option = None | Some of 'a
let showValue = Option . fold ( fun _ x -> sprintf "値は: %d" x ) "値なし"
let full =一部42 let empty =なし
showValueがいっぱいです|> printfn "showValue がいっぱいです -> %s" showValueが空です|> printfn "showValue が空です -> %s"
showValue full -> 値は: 42
showValue empty -> 値なし
ハスケル
Haskellではオプション型は次のように定義されます。[6]data Maybe a = Nothing | Just a
showValue :: Maybe Int -> String showValue = foldl ( \ _ x -> "値は: " ++ show x ) "値なし"
main :: IO () main = do let full = Just 42 let empty = Nothing
putStrLn $ "showValue full -> " ++ showValue full putStrLn $ "showValue empty -> " ++ showValue empty
showValue full -> 値は: 42
showValue empty -> 値なし
イドリス
Idris では、オプション タイプは として定義されます。
data Maybe a = Nothing | Just a
showValue : Maybe Int -> String
showValue = foldl (\ _ , x => "値は " ++ show x ) "値なし"
main : IO ()
main = do let full = Just 42 let empty = Nothing
putStrLn $ "showValue full -> " ++ showValue full
putStrLn $ "showValue empty -> " ++ showValue empty
showValue full -> 値は: 42
showValue empty -> 値なし
ニム
std /オプションをインポートする
proc showValue ( opt : Option [ int ] ): string = opt . map ( proc ( x : int ): string = "値は: " & $ x . get ( "値なし" )
満杯
=いくつか( 42 )空=なし( int )
echo "showValue(full) -> " 、showValue ( full ) echo "showValue(empty) -> " 、showValue ( empty )
showValue(full) -> 値は: 42
showValue(empty) -> 値なし
オカムル
OCamlではオプション型は次のように定義されます。[7]type 'a option = None | Some of 'a
let show_value =
Option . fold ~ none : "値なし" ~ some :( fun x -> "値は: " ^ string_of_int x )
let () =
let full = Some 42 in
let empty = None in
print_endline ( "show_value full -> " ^ show_value full );
print_endline ( "show_value empty -> " ^ show_value empty )
show_value full -> 値は42です
show_value empty -> 値がありません
さび
Rustではオプション型は次のように定義されます。[8]enum Option<T> { None, Some(T) }
fn show_value ( opt : Option < i32 > ) -> String {
opt . map_or ( "値がありません" . to_owned (), | x | format! ( "値は: {}" , x )) }
fn main () { let full = Some ( 42 ); let empty = None ;
println! ( "show_value(full) -> {}" 、show_value ( full )); println! ( "show_value(empty) -> {}" 、show_value ( empty )); }
show_value(full) -> 値は42です
show_value(empty) -> 値はありません
スカラ
Scala では、オプション型はおよびによって拡張された型として定義されます。
sealed abstract class Option[+A]final case class Some[+A](value: A)case object None
object Main : def showValue ( opt : Option [ Int ]): String = opt . fold ( "値なし" )( x => s"値は: $ x " )
def main ( args :配列[文字列] ):単位= val full = Some ( 42 ) val empty = None
println ( s"showValue(full) -> ${ showValue ( full ) } " ) println ( s"showValue ( empty) -> ${ showValue ( empty ) } " )
showValue(full) -> 値は: 42
showValue(empty) -> 値なし
標準ML
標準 ML では、オプション タイプは として定義されます。
datatype 'a option = NONE | SOME of 'a
迅速
Swiftではオプション型は と定義されますが、一般的には と記述されます。[9]enum Optional<T> { case none, some(T) }T?
func showValue ( _ opt : Int ?) -> String {
return opt . map { "値は: \( $0 ) " } ?? "値なし"
}
満杯 = 42空に: Int ? = nil
print ( "showValue(full) -> \( showValue ( full )) " )
print ( "showValue(empty) -> \( showValue ( empty )) " )
showValue(full) -> 値は: 42
showValue(empty) -> 値なし
ジグ
?i32Zig では、オプションの型にするには、
型名の前に ? を追加します。
ペイロードn は、 などのifまたはwhileステートメントでキャプチャでき、 の場合はelse句が評価されます。
if (opt) |n| { ... } else { ... }null
const std = @import ( "std" );
fn showValue ( allocator : std . mem . Allocator , opt : ? i32 ) ! [] u8 { return if ( opt ) | n | std . fmt . allocPrint ( allocator , "値は: {}" , .{ n }) else allocator . dupe ( u8 , "値なし" ); }
pub fn main () ! void { // アロケータを設定し、メモリの解放を忘れた場合は警告します。var gpa = std . heap . GeneralPurposeAllocator (.{}){}; defer std . debug . assert ( gpa . deinit () == . ok ); const allocator = gpa . allocator ();
// 標準出力ストリームを準備します
。const stdout = std.io.getStdOut ( ) . writer ( ) ;
// 例を実行します
。const full = 42 ; const empty = null ;
const full_msg = try showValue ( allocator , full ); defer allocator . free ( full_msg ); try stdout . print ( "showValue(allocator, full) -> {s} \n " , .{ full_msg });
const empty_msg = try showValue ( allocator , empty ); defer allocator . free ( empty_msg ); try stdout . print ( "showValue(allocator, empty) -> {s} \n " , .{ empty_msg }); }
showValue(allocator, full) -> 値は42です。
showValue(allocator, empty) -> 値はありません。
参照
参考文献
- ^ Milewski, Bartosz (2015-01-13). 「単純な代数的データ型」。Bartosz Milewski の Programming Cafe。 合計型。 「Maybe を次のようにエンコードすることもできます: data Maybe a = Either () a」。 2019-08-18 にオリジナルからアーカイブ。2019-08-18に取得。
- ^ 「A Fistful of Monads - 素晴らしいHaskellを学ぼう!」www.learnyouahaskell.com 。 2019年8月18日閲覧。
- ^ Hutton, Graham (2017年11月25日). 「モナドとは何か?」Computerphile Youtube . 2021年12月20日時点のオリジナルよりアーカイブ。2019年8月18日閲覧。
- ^ 「Maybe · Elm 入門」. guide.elm-lang.org .
- ^ 「オプション」. fsharp.org . 2024年10月8日閲覧。
- ^ 「6 定義済み型とクラス」www.haskell.org . 2022年6月15日閲覧。
- ^ 「OCamlライブラリ:オプション」。v2.ocaml.org 。 2022年6月15日閲覧。
- ^ 「core::option のオプション - Rust」. doc.rust-lang.org . 2022-05-18 . 2022-06-15閲覧。
- ^ 「Apple Developer Documentation」。developer.apple.com 。 2020年9月6日閲覧。
