F# と C# の記法比較

MSDN F# リファレンスを使い C# と記法を比較する

型推論

型推論

型推論 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"); 
}