ここにもあった... F#ドキュメントには未掲載のOptionの関数

> * ※以下はF#のドキュメントが更新されれば不必要になるでしょう。
> * 前置きをスキップするときは「Optionモジュールの未掲載関数」からお読みください。

F#はMicrosoftの[Don Syme](https://twitter.com/dsyme "https://twitter.com/dsyme")氏が開発したプログラミング言語で、命令型、オブジェクト指向、関数型の要素を併せ持つマルチパラダイム言語と[位置付けられています](https://msdn.microsoft.com/visualfsharpdocs/conceptual/visual-fsharp "https://msdn.microsoft.com/visualfsharpdocs/conceptual/visual-fsharp")。実装はオープンソースの[MITライセンス](https://github.com/fsharp/fsharp/blob/master/License.txt "https://github.com/fsharp/fsharp/blob/master/License.txt")のもと、[githubのリポジトリ](https://github.com/fsharp/fsharp "https://github.com/fsharp/fsharp")で公開されています。

実行環境は.NET Frameworkおよび.NET CoreやMonoといったマルチプラットフォームに対応していますが、サポート状況については各プラットフォームごとの情報を参照してください(「[F# の概要](https://docs.microsoft.com/ja-jp/dotnet/fsharp/get-started/index "https://docs.microsoft.com/ja-jp/dotnet/fsharp/get-started/index")」など)。

# Optionについて

`Option`は、検索など結果を得られないかもしれないときの戻り値としてよく利用される型です。結果が存在するときは`Some result`(resultが結果)、存在しないときは`None`という値で表します。型名は`'T option`(`'T`は`result`の型名)で表されます。

`Some result`から`result`を得るには、`match-with`で処理の振り分けを行います。これにより、値が`Some result`のときと`None`のとき、それぞれの処理を設定できます。たとえば`List.tryFind`関数で得られた結果を表示するには、以下のようにできます。

```fsharp:List.tryFind関数の結果を取得
let findName (name: string) =
  // 検索処理(見つからない場合もある)
  let result =
    ["F#"; "C#"; "VB"]
    |> List.tryFind (fun (s: string) -> s.IndexOf(name) >= 0)
  // 処理の振り分け
  match result with
  | Some n -> printfn "%Aが見つかりました" n
  | None   -> printfn "見つかりませんでした"

findName "#"    // "F#"が見つかりました
findName "PS"   // 見つかりませんでした
```

# Optionのメンバー関数
`Option`型の定義は`type Option<'T> = None | Some of 'T`と`type 'T option = Option<'T>`ですが、これ以外にメンバー関数も実装されています([詳細](https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option%5b%27t%5d-union-%5bfsharp%5d "https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option%5b%27t%5d-union-%5bfsharp%5d"))。メンバー関数には、通常のメンバー関数と`static`なメンバー関数があります。

```fsharp:Optionのメンバー関数
let opt = Some 1

opt.IsSome  // true
opt.IsNone  // false
opt.Value   // 1
```

```fsharp:Optionのstaticメンバー関数
Option<int>.None    // 通常はNoneで表す
Option<int>.Some 1  // 通常はSome 1で表す
```

# Optionモジュールの未掲載関数
`Option<'T>`型の値(以下`Option`値)に対して実行できる関数には、メンバー関数のほかに[Optionモジュール](https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option-module-%5bfsharp%5d "https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option-module-%5bfsharp%5d")の関数もあります。これらは引数に`Option`値を設定して実行されます。関数にはF#ドキュメントに掲載されていない__未掲載関数__も存在します。ここでは[2017/8/18更新分](https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option-module-%5bfsharp%5d "https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.option-module-%5bfsharp%5d")のドキュメントに掲載されていない関数を紹介していきます。

## Option.contains 値 Option値<br>('a -> 'a option -> bool) when 'a : equality
`Some a`における`a`の値が引数と一致するかを確かめ、`true`か`false`のどちらかを判定します。`Option`値が`None`であれば必ず`false`です。

```fsharp:Option.contains
Option.contains 3 (Some 3)  // true
Option.contains 3 (Some 1)  // false
Option.contains 3 (None)    // false
```

## Option.defaultValue デフォルト値 Option値<br>'a -> 'a option -> 'a
`Option`値の`Some a`から`a`を取得できるときは`a`を、できないときは引数のデフォルト値を得られる関数です。`a`の型とデフォルト値の型とを同一にしてください。

```fsharp:Option.defaultValue
Option.defaultValue -1 (Some 3)  // 3
Option.defaultValue -1 (None)    // -1
```

## Option.defaultWith デフォルト関数 Option値<br>(unit -> 'a) -> 'a option -> 'a
`Option.defaultValue`と似ていますが、引数の`Option`値が`None`のときはデフォルト関数を実行します。この関数に引数はありません。また、関数の戻り値の型は`Some a`の`a`の型と同一にしてください。

```fsharp:Option.defaultWith
Option.defaultWith (fun _ -> -1) (Some 3)  // 3
Option.defaultWith (fun _ -> -1) None      // -1
```

## Option.map2 関数 Option値a Option値b<br>('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option
`Option`値aが`Some a`で、`Option`値bが`Some b`のとき、`a`と`b`の値を引数とする関数を実行します。この結果に`Some`がつけられ、`map2`関数の結果となります。どちらかの`Option`値がNoneのときは結果も必ず`None`となります。

```fsharp:Option.map2
Option.map2 (fun x y -> x + y) (Some 2) (Some 3)  // Some 5
Option.map2 (fun x y -> x + y) (Some 2) None      // None
Option.map2 (fun x y -> x + y) None (Some 3)      // None
```

## Option.map3 関数 Option値a Option値b Option値c<br>('a -> 'b -> 'c -> 'd) -> 'a option -> 'b option -> 'c option -> 'd option
`Option`値aが`Some a`、`Option`値bが`Some b`、`Option`値cが`Some c`のとき、`a`、`b`、`c`の値を引数とする関数を実行します。この結果に`Some`がつけられ、`map3`関数の結果となります。どれかの`Option`値がNoneのときは結果も必ず`None`となります。

```fsharp:Option.map3
Option.map3 (fun x y z -> x + y + z) (Some 2) (Some 3) (Some 4) // Some 9
Option.map3 (fun x y z -> x + y + z) (Some 2) (Some 3) None     // None
Option.map3 (fun x y z -> x + y + z) (Some 2) None     (Some 4) // None
Option.map3 (fun x y z -> x + y + z) None     (Some 3) (Some 4) // None
```

## Option.orElse デフォルトOption値 Option値<br>'a option -> 'a option -> 'a option
`Option`値が`Some a`なら結果もそのまま、`None`であれば結果がデフォルトOption値となります。2つの引数の型はどちらも同一にしてください。

```fsharp:Option.orElse
Option.orElse (Some -1) (Some 3)  // Some 3
Option.orElse (Some -1) None      // Some -1
```

## Option.orElseWith デフォルトOption関数 Option値<br>(unit -> 'a option) -> 'a option -> 'a option
`Option.orElse`と似ていますが、`Option`値が`None`のときはデフォルト`Option`関数の結果となります。この関数に引数はありません。結果と`Option`値の型は同一にしてください。

```fsharp:Option.orElseWith
Option.orElseWith (fun _ -> Some -1) (Some 3)  // Some 3
Option.orElseWith (fun _ -> Some -1) None      // Some -1
```

## Option.ofNullable Nullable値<br>Nullable<'a> -> 'a option (詳細略)
[Nullable<'T>](https://docs.microsoft.com/ja-jp/dotnet/api/system.nullable-1?view=netframework-4.7.1 "https://docs.microsoft.com/ja-jp/dotnet/api/system.nullable-1?view=netframework-4.7.1")型の引数を`'T option`型に変換します。具体的には、値を持つ(`HasValue = true`の)`Nullable`オブジェクトは`Some`、値を持たない(`HasValue = false`の)`Nullable`オブジェクト(`null`相当)は`None`に変換されます。

```fsharp:Option.ofNullable
open System
Option.ofNullable (Nullable 1)       // Some 1
Option.ofNullable (Nullable<int>())  // Option<int>.None (int option型のNone)
```

---
ドキュメントが更新されたら、このページは不要になると思いますが、その時までご覧になった方々の参考になればと思います。