型推論
型推論
型推論 Type Inference
元ネタ http://msdn.microsoft.com/ja-jp/library/dd233180.aspx
パラメーターおよび戻り値の型の推論
たとえば、次のコードでは、パラメーターの型 a および b と戻り値の型は、いずれも int と推論されます。これは、リテラルの 100 が int 型であるためです。
F#
let f a b = a + b + 100
C# の場合、引数の型推論はできないので、普通に関数を作る。
C#
int f(int a, int b) { return a + b + 100; }
特定の型でのみ使用できる関数やメソッドなど、型に対する制限を意味する他の構成要素を使用して、型推論を操作することもできます。 わざと曖昧さを除去することもできる。
F#
// Type annotations on a parameter. let addu1 (x : uint32) y = x + y // Type annotations on an expression. let addu2 x y = (x : uint32) + y
すべてのパラメーターの後ろに型の注釈を記入して、関数の戻り値を明示的に指定することもできます。
F#
let addu1 x y : uint32 = x + y
一般的にパラメーターの型の注釈が役立つケースには、パラメーターがオブジェクト型であり、メンバーを使用する場合があります。 この場合、string が指定されていないと、'a になるので、Replace メソッドを指定したときにコンパイルエラーになる。
F#
let replace(str: string) = str.Replace("A", "a")
例えば、T のままでは .Replace メソッドが使えないが、string で制約することで .Replace が使えるようになる...のだが、これはコンパイルが通らない。何か良い例はないか?
C#
class StringEx<T> where T : string { public string replace( T str ) { return str.Replace("A", "a"); } }
自動ジェネリック
次の関数は、任意の型の 2 つのパラメーターを組み合わせて 1 つのタプルにします。
F#
let makeTuple a b = (a, b)
型は、次のように推論されます。
F#
'a -> 'b -> 'a * 'b
C# の場合には引数に型推論が適用できないが、少し楽にタプルを作ることもできる。
C#
class TupleEx<T> { public static Tuple<T, T> MakeTuple(T a, T b) { return new Tuple<T, T>(a, b); } } public void test() { // int 型のタプル var t1 = TupleEx<int>.MakeTuple(10, 20); // string 型のタプル var t2 = TupleEx<string>.MakeTuple("masuda", "tomoaki"); }