次の方法で共有


オプション

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.isSomeOption.isNone は、オプションが値を保持するかどうかをテストする両方のモジュール関数です。 Option.get は、 値がある場合その値を取得します。 値がない場合は、System.ArgumentException をスローします。

Option.bind 関数は、値がある場合に値に対して関数を実行します。 関数は引数を 1 つだけ受け取る必要があり、そのパラメーター型はオプション型である必要があります。 関数の戻り値は別のオプション型です。

オプション モジュールには、リスト、配列、シーケンス、およびその他のコレクション型で使用できる関数に対応する関数も含まれています。 これらの関数には、Option.mapOption.iterOption.forallOption.existsOption.foldBackOption.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 関数を使用すると、パターン マッチングなしで、SomeNone の両方のケースをシームレスに処理できます。

関連項目