オプション
F# のオプション型は、名前付き値または変数に実際の値が存在しない可能性がある場合に使用されます。 オプションには基になる型があり、その型の値を保持することも、値を持たない場合もあります。
Remarks
次のコードは、オプション型を生成する関数を示しています。
let keepIfPositive (a: int) = if a > 0 then Some(a) else None
ご覧のように、入力 a
が 0 より大きい場合は、Some(a)
が生成されます。 それ以外の場合は、None
が生成されます。
None
値は、オプションに実際の値がない場合に使用されます。 それ以外の場合、式 Some( ... )
はオプションに値を与えます。 Some
値と None
値は、次の関数 exists
のようにパターン マッチングに役立ちます。この関数は、オプションに値がある場合は true
を返し、そうでない場合は false
を返します。
let exists (x: int option) =
match x with
| Some(x) -> true
| None -> false
オプションの使用
オプションは、次のコードに示すように、検索で一致する結果が返されない場合に一般的に使用されます。
let rec tryFindMatch pred list =
match list with
| head :: tail -> if pred (head) then Some(head) else tryFindMatch pred tail
| [] -> None
// result1 is Some 100 and its type is int option.
let result1 = tryFindMatch (fun elem -> elem = 100) [ 200; 100; 50; 25 ]
// result2 is None and its type is int option.
let result2 = tryFindMatch (fun elem -> elem = 26) [ 200; 100; 50; 25 ]
前のコードでは、リストが再帰的に検索されます。 関数 tryFindMatch
は、ブール値と検索するリストを返す述語関数 pred
を受け取ります。 述語を満たす要素が見つかった場合、再帰は終了し、関数は Some(head)
式のオプションとして値を返します。 空のリストが一致すると、再帰は終了します。 その時点で、head
値が見つからず、None
が返されます。
存在する可能性がある値または存在しない値をコレクションで検索する多くの F# ライブラリ関数は、option
型を返します。 慣例により、これらの関数は try
プレフィックス (例: Seq.tryFindIndex
) で始まります。
オプションは、値が存在しない可能性がある場合にも役立ちます。たとえば、値を構築しようとしたときに例外がスローされる可能性がある場合などです。 次のコード例は、これを示しています。
open System.IO
let openFile filename =
try
let file = File.Open(filename, FileMode.Create)
Some(file)
with ex ->
eprintf "An exception occurred with message %s" ex.Message
None
前の例の openFile
関数は、ファイルが正常に開くと File
オブジェクトを返し、例外が発生した場合に None
するため、型 string -> File option
を持っています。 状況によっては、例外の伝達を許可するのではなく、例外をキャッチするのが適切な設計上の選択ではない場合があります。
さらに、null
または null 値をオプションの Some
ケースに渡すことができます。 これは一般に回避する必要があり、通常は F# のルーチン プログラミングですが、.NET の参照型の性質により可能です。
オプションのプロパティとメソッド
オプションの種類では、次のプロパティとメソッドがサポートされています。
プロパティまたはメソッド | 種類 | 説明 |
---|---|---|
None |
'T option |
None 値を持つオプション値を作成する静的メンバー。 |
IsNone | bool |
オプションに None 値がある場合は、true を返します。 |
IsSome | bool |
オプションに None されていない値がある場合は、true を返します。 |
Some |
'T option |
None ではない値を持つオプションを作成する静的メンバー。 |
値 | 'T |
基になる値を返すか、値が None 場合は System.NullReferenceException をスローします。 |
オプション モジュール
オプションに対して操作を実行する便利な関数を含むモジュール Optionがあります。 一部の関数はプロパティの機能を繰り返しますが、関数が必要なコンテキストで役立ちます。 Option.isSome と Option.isNone は、オプションが値を保持するかどうかをテストする両方のモジュール関数です。 Option.get は、 値がある場合その値を取得します。 値がない場合は、System.ArgumentException
をスローします。
Option.bind 関数は、値がある場合に値に対して関数を実行します。 関数は引数を 1 つだけ受け取る必要があり、そのパラメーター型はオプション型である必要があります。 関数の戻り値は別のオプション型です。
オプション モジュールには、リスト、配列、シーケンス、およびその他のコレクション型で使用できる関数に対応する関数も含まれています。 これらの関数には、Option.map
、Option.iter
、Option.forall
、Option.exists
、Option.foldBack
、Option.fold
、および Option.count
が含まれます。 これらの関数を使用すると、0 個または 1 個の要素のコレクションのようにオプションを使用できます。 詳細と例については、リストのコレクション関数の説明を参照してください。
他の型への変換
オプションは、リストまたは配列に変換できます。 オプションがこれらのデータ構造のいずれかに変換されると、結果のデータ構造には 0 または 1 の要素があります。 オプションを配列に変換するには、Option.toArray
を使用します。 オプションをリストに変換するには、Option.toList
を使用します。
既定値を使用したオプションの変換
リストや配列への変換に加えて、Option.defaultValue
関数を使用して既定値を指定することで、オプションを他の型に変換できます。 これは、値が None
されていないことを確認する場合に特に便利です。 例えば:
let optionString = Some("F#")
let defaultString = optionString |> Option.defaultValue ""
// defaultString is "F#"
let optionInt = None
let defaultInt = optionInt |> Option.defaultValue 0
// defaultInt is 0
Option.defaultValue
関数を使用すると、パターン マッチングなしで、Some
と None
の両方のケースをシームレスに処理できます。
関連項目
.NET