型の推論 (F#)

このトピックでは、F# コンパイラが値、変数、パラメーター、および戻り値の型を推論する方法について説明します。

一般的な型の推論

型の推論を行うことによって、コンパイラが推論によって型を確定できない場合以外は、F# の構成要素の型を指定する必要がなくなります。 型情報を明示的なに指定しないということは、F# が動的に型指定される言語であるという意味でも、F# の値が弱く型指定されているという意味でもありません。 F# は、厳密に型指定された言語です。つまり、コンパイラはコンパイル時に、各構成要素の正確な型を推定します。 情報が不足しているためにコンパイラが各構成要素の型を推定できない場合は、通常、コードのどこかに明示的な型の注釈を加えて、追加の型情報を指定する必要があります。

パラメーターおよび戻り値の型の推論

パラメーター リストで、各パラメーターの型を指定する必要はありません。 また、F# は静的に型指定された言語であるため、すべての値および式にはコンパイル時に明確な型があります。 明示的に指定しない型については、コンパイラがコンテキストに基づいて型を推論します。 型が特定できない場合、その型はジェネリックと推論されます。 コードで値の使用法が一貫しておらず、値のすべての使用法を満たす単一の型を推論できない場合、コンパイラはエラーを報告します。

関数の戻り値の型は、関数内の最後の式の型によって判断されます。

たとえば、次のコードでは、パラメーターの型 a および b と戻り値の型は、いずれも int と推論されます。これは、リテラルの 100 が int 型であるためです。

let f a b = a + b + 100

リテラルを変更することにより、型の推論を操作できます。 サフィックス u を追加して 100 を uint32 にした場合、a、b、および戻り値の型は、uint32 と推論されます。

また、特定の型でのみ使用できる関数やメソッドなど、型に対する制限を意味する他の構成要素を使用して、型の推論を操作することもできます。

また、次の例に示すように、関数やメソッドのパラメーター、または式の変数に、明示的な型の注釈を適用することもできます。 異なる制約の間で衝突が発生した場合、エラーが発生します。

// Type annotations on a parameter.
let addu1 (x : uint32) y =
    x + y

// Type annotations on an expression.
let addu2 x y =
    (x : uint32) + y

また、すべてのパラメーターの後ろに型の注釈を記入して、関数の戻り値を明示的に指定することもできます。

let addu1 x y : uint32 =
   x + y

一般的にパラメーターの型の注釈が役立つケースには、パラメーターがオブジェクト型であり、メンバーを使用する場合があります。

let replace(str: string) =
    str.Replace("A", "a")

自動汎化

関数のコードがパラメーターの型に依存しない場合、コンパイラはそのパラメーターをジェネリックと見なします。 これは自動汎化と呼ばれ、記述するジェネリック コードの複雑化を防止するために非常に役立ちます。

たとえば、次の関数は、任意の型の 2 つのパラメーターを組み合わせて 1 組にします。

let makeTuple a b = (a, b)

型は、次のように推論されます。

'a -> 'b -> 'a * 'b

追加情報

型の推論の詳細については、F# 言語仕様を参照してください。

参照

その他の技術情報

自動汎化 (F#)