関数の型註釈
関数定義の時に型を明示しなくても推論で型を決めてくれるけど、明示したいこともある。
例えば、** 演算子は float 型専用なので他の型では使えない。
let pow x y = x ** y
pow "2" "10" //=> error FS0001: This expression was expected to have type float but here has type string
そこで型註釈が必要なのだが。
let pow (x:string) (y:string) = (float x) ** (float y) |> string
pow "2" "10" //=> "1024"
期待通りには動くが、pow の定義の型註釈がとても見にくい。
引数ひとつひとつに註釈するのではなく、関数全体の型をまとめてかければその方が見やすかろう。その方法もある。
F# では変数の型註釈を
let x : int = 42
という風に識別子と値の間に書くことができる。
そして関数もファーストクラスであり、無名関数を識別子に束縛することで関数定義ができるわけで、要するに変数と同じように関数も型註釈ができる。
let pow : string -> string -> string = fun x y -> (float x) ** (float y) |> string
ちょっと haskell に似てる。まず関数の型を記述してその後に定義を記述する。
この記法なら型註釈も億劫じゃない。
ただ、一つ前に書いた「引数に個別に型註釈を付けたコード」と比べると「fun x y ->」が入る分、インデントが1つ深くなってしまう。
それが嫌なら一応これでもいける。
let pow : string -> string -> string = fun x y -> (float x) ** (float y) |> string
let と fun は同じインデントレベルになってもいいみたい。流石にこれは抵抗あるかな? 慣れりゃなんてことないと思うけど...
ちょっと変えた
本文のコード int だと話がややこしくなるので、string にしました。