2016-09-08 3 views
4

以下のスニペットでは、fgという方法の機能を説明することができません。fooは機能しません。それをするために。値の制限:タイプ 'bar'がジェネリックタイプを持っていると推測されました

let f a b = a,b 
let g (a : 'a) (b : 'a) = a 

let (>!) f1 f2 = 
    fun a b -> 
     let (x,y) = f1 a b 
     f2 x y 

let foo = fun a b -> (f >! g) a b 
let bar = f >! g 

barが機能しない理由誰もが、私には説明できますか? fooにもジェネリックタイプがあるとすれば、それは私には意味がありません。

+0

gの引数に同じ型があり、fが2つの異なる型を受け入れるという制限を追加しました –

+0

@PanagiotisKanavos '' g''の引数に注釈を付けずに、 '' a - > ' b - > 'a''。だから私は今、それが "a - > a a - > a"であるとすれば、それがなぜ変わるのか分からない。 – BitTickler

答えて

7

fooは関数であり、barは値です。はい、関数型の値ですが、依然として値です。そこには微妙な違いがあります。

fooは、fun ->の直後に表示されるので、fooが関数であることを「見る」ことができます。letの直後です。

barは、真の値です。これは、別の関数(演算子>!)を呼び出した結果です。 F#には、一般的な引数が明示的に指定されていない限り、値(別の関数とは異なる)が汎用型を持つことができないという(日常的な意味での)ルールがあり、それを効果的に "型関数"にします。

これはF#に特有のものではありませんが、他の非純粋なMLの亜種もこれを持っています(これは少し複雑です)。 HereはF#のこのルールの説明であり、here'sのSMLの説明です。

+1

それは何かが間違っていることを示唆していませんか?機能は最終的にファーストクラスの市民ではないのですか? ''>! ''の返り値は '' foo''の定義が関数であるのと同様の関数です。 – BitTickler

+0

私が提供したリンクを読んでください。 –

+2

しかし、これは関数のファーストクラスではなく、構文と定義の問題です。他の同様の例があります。モジュールで定義された関数は、静的クラスで定義された関数と異なり、ローカルコンテキストで定義されたものとは異なります。別の例 - たとえ関数が「値」であっても、その汎用性は含まれていません。つまり、インスタンス化せずに汎用関数を渡すことはできません。 –

関連する問題