さて、今回は小ネタです。小ネタだけど要所要所でお世話になるオプション型というものを紹介したいと思います。オプション型というのは値がある場合と無い場合があるという状態を表したいときに使います。C#とかでは一般的にnullが使われるような状態で使われるものですね。
たとえば以下のようなケースです。
int? GetValue(int i) { return i % 2 == 0 ? null : i; }
処理としては意味ないですが偶数だとnullを返して奇数だとそのまま数字を返すような処理です。これをF#のoptionを使って書き直してみます。
// 偶数だったらNone 奇数だったらSome iを返す let getValue i = if i % 2 = 0 then None else Some i // 呼び出してみる printfn "%A" <| getValue 2 printfn "%A" <| getValue 3
opetion型は何も値がないNoneと何か値を持つSome 値 という2パターンを持ちます。Someの後には任意の値を渡すことができます。
次に、option型から値を取得したりする方法を見てみようと思います。option型にはIsSome, IsNone, Valueといったプロパティが定義されているので、これらのプロパティを使って値を取得したりできます。
(ただ、このプロパティを使って値をとるとかいうことは、本当はあまりしないけど、それは次の回あたりで説明します)
// 任意の型のoptionを受け取ってプロパティの値を表示する let printOption (v : 'a option) = printfn "IsSome = %A" v.IsSome printfn "IsNone = %A" v.IsNone printfn "Value = %A" v.Value // 二種類のoptionを用意して let v1 = Some "Hello" let v2 = None // 状態を表示してみる printOption v1 printOption v2
実行結果は以下のようになります。
IsSome = true IsNone = false Value = "Hello" IsSome = false IsNone = true System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。 場所 FSI_0001.printOption[a](FSharpOption`1 v) 場所 hoge.fsx:行 4 場所 <StartupCode$FSI_0001>.$FSI_0001.main@() 場所 hoge.fsx:行 10
最後がNullReferenceExceptionになっていますが、これはNoneに対してValueを呼び出すと起きてしまいます。なのでNoneから値はどう頑張っても取得できません。
Option型は、結果が成功するか失敗するかよくわからない関数の戻り値によく使われています。C#とかだとnullだったりしますが、nullより安全?なoption型がF#ではデファクトみたいです。
なので、よくお世話になる型なので覚えておきましょう。そして、本当はもっと便利に使える方法もあるので、それについて次回説明したいと思います。
過去記事
- 手軽なスクリプト言語としてのF#
- 手軽なスクリプト言語としてのF# その2
- 手軽なスクリプト言語としてのF# その3
- 手軽なスクリプト言語としてのF# その4
- 手軽なスクリプト言語としてのF# その5
- 手軽なスクリプト言語としてのF# その6
- 手軽なスクリプト言語としてのF# その7
- 手軽なスクリプト言語としてのF# その8「レコード」
- 手軽なスクリプト言語としてのF# その9「クラス」
- 手軽なスクリプト言語としてのF# その10「継承・アブストラクトクラス」
- 手軽なスクリプト言語としてのF# その11「インターフェースと演算子のオーバーロード」
- 手軽なスクリプト言語としてのF# その12「ラムダ式とイベント」
- 手軽なスクリプト言語としてのF# その13「オブジェクト初期化子みたいなの」
- 手軽なスクリプト言語としてのF# その14「合成演算子とパイプ演算子」
- 手軽なスクリプト言語としてのF# その15「WPFしてみた」
- 手軽なスクリプト言語としてのF# その16「総称型 ジェネリック」
- 手軽なスクリプト言語としてのF# その17「リスト」