2012-03-20 6 views
1

F#の型推論の動作を理解できません。演算子stringはコンパイル時には実行時ではなく、let lowerstring = string >> (fun s -> s.ToLowerInvariant())のようなものが一般化されていないため、静的型ディスパッチを使用します。コンパイラは引数の型を知る必要があります。しかし、私はいくつかの奇妙なことを私に見ている。以下の定義ではなぜ私の関数は直感的に一般化されないのですか?

// val token: JToken 
// val num: int 

let tokstr1 = lowerstring1 token // lowerstring1 now has type JToken -> string 
let numstr1 = lowerstring1 num // Error, doesn't compile 

(* As above with lowerstring2 and lowerstring3 *) 

let tokstr4 = lowerstring4 token // lowerstring4 now has type 'a -> string 
let numstr4 = lowerstring4 num // no error, works as 'expected' 

lowerstring3lowerstring4が異なっ型検査されている理由は、私は明確ではないよ。私はこの動作を観察

let inline lower (s: string) = s.ToLowerInvariant() 

// 'T -> string, constrained to the type of its first use 
let lowerstring1 = string >> lower 

// Same as above 
let lowerstring2 value = value |> string |> lower 

// Same as above 
let lowerstring3 = box >> string >> lower 

// 'a -> string, fully generalized 
let lowerstring4 value = value |> box |> string |> lower 

。静的な制約があると思われますが、その場合、lowerstring4は一般化できませんでしたか?関数の引数が明示的に存在すると、ここで違いが生じるのはなぜですか?

+3

最初の汎用ことができない_value_、です。後者はできる関数です。 'インライン'を紹介し、本当に楽しい時間を過ごしてください。 – ildjarn

答えて

1

F#はILに下位のコードを付けなければならず、.NETには一般的な '値'が存在しないため、関数は真の構文関数(汎用の.NETメソッドに生成される)のときにのみ作成されます。

(一つ例外は[<GeneralizableValueAttribute>]あり、例えばhere参照。)

関連する問題