お前もnullにしてやろうか! #FsAdvent
この記事はF# Advent Calendar 2015の31日目の記事です。
ガス欠なので役に立たないネタでお茶を濁します。
Noneはnullと解釈できる
F#erの皆様はたいていprintf "%A" None
を実行して<null>
と表示されることに落胆したことがあるのではないでしょうか。
私は落胆しました。
同じようなことをやってみる
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>] type A<'T> = B | C of 'T with [<CompilationRepresentation(CompilationRepresentationFlags.Instance)>] member this.Value = match this with | C a -> a | B -> failwith "oops!
CompilationRepresentationFlags.UseNullAsTrueValue
を指定することで、引数をとらない識別子をnullとして表現可能になります。
こいつを付けた状態でメンバーにCompilationRepresentationFlags.Instance
を付けなかったら、そのメンバーは静的にコンパイルされます。
使いどころは?
- .NETが絡む
- その判別共用体の中で引数をとらない識別子が一つのみ
- nullにしてもよいと思った場合
これがそろったら使うか…? くらいの認識です。 ぶっちゃけ使うことはないだろうと思っています。
気を付けるべきとき
自分は使わないとはいえ、どのライブラリも使わないということは言えないので、対処してあげる必要があったりします。
ぱっと思いつく罠にはまるパターンはPretty Printerですね。
あとは box
したときにやらかしそうとかですかね。
結論
使うな。だが注意せよ。
追記
こうしてnullに表現可能になった識別子は、コンパイルしたらUnchecked.defaultof
でnullではなく代わりにunion caseのほうが使われるみたいですね。
F# Interactiveではnullが返ってきたので、コンパイラが色々やっている模様。