6. F# の型推論
F #では、変数や関数を定義するのに型を書かなくてもよい。
// string 型の変数
let name = "gab_km"
//=> val name : string = "gab_km"
// int 型の値を 2 つ取り、それらの和である int 型の値を返す関数
let add x y = x + y
//=> val add : int -> int -> int
これを可能にするのが、型推論という仕組み。
束縛した値や使用している演算子から、適切な型を推論して
いる。
8. 自動ジェネリック化の限界
以下のような場合を考える。
// 本当は 'a -> 'a -> 'a に型推論してほしいけど…
let add x y = x + y
//=> val add : int -> int -> int
この add 関数がジェネリックにならないのは、 (+) 演算子が
デフォルトで int 型を取るようになっているため。
どうにかできないだろうか?
10. 静的に解決された型パラメータ
ジェネリック型の制約にメンバー制約を付与することができる
が、静的に解決された型パラメータを使うことで、構造的部分型
めいた型チェック 1
を行うことができるようになる。
let b = { Name = "John Doe" }
//=> val b : B = {Name = "John Doe";}
let c = { Money = 10000 }
//=> val c : C = {Money = 10000;}
let ab = { Person = b }
//=> val ab : A<B> = {Person = {Name = "John Doe";};}
let ac = { Person = c }
//=> error FS0001: The type 'C' does not support any operators named
'SayHello'
1: 本日のマサカリポイント
11. inline キーワード
関数定義に inline キーワードを付与すると、その関数は呼び出
し元にインライン展開される。これにより、 inline 関数は呼び
出し元で型推論されるようになる。
// inline キーワードを指定した addInline 関数
let inline addInline x y = x + y
//=>val inline addInline :
// ^a -> ^b -> ^c
// when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
2: 本日のマサカリポイント (2)
その結果、 addInline 関数は「引数のいずれかが (+) 演算子
を持つ型である」と推論される 2
。
12. inline キーワード
inline キーワードを使って定義した関数やメソッドは、非常に
柔軟な型パラメータを持った関数になる。
addInline 1 2
//=>val it : int = 3
addInline 1.5 2.3
//=>val it : float = 3.8
addInline “hoge” “fuga”
//=>val it : string = “hogefuga”
先の addInline 関数は、 (+) 演算子を持つ型を引数に取ること
ができる。