2010-11-25 13 views
1

誰かが私を説明することができ、なぜ引数と行動の数が異なる これらの関数は行うが、 同じ型シグネチャ、まだ彼らは両方とも正しいですか?Haskellの型シグネチャの質問

comp1 :: (a -> b) -> (b -> c) -> a -> c 
comp1 f g = g.f 

comp2 :: (a -> b) -> (b -> c) -> a -> c 
comp2 f g x = g (f x) 

も、なぜCOMP2は

comp2 :: (a -> b) -> (b -> c) -> a -> c 

代わりの

comp2 :: a -> (a -> b) -> (b -> c) -> a -> c 

のようなものを持っているのでしょうか?

ありがとうございます。

+2

http://www.haskell.org/haskellwiki/Eta_conversion? –

+3

どのようにして2つの機能が異なる動作をしますか?私と同じように見える... – sepp2k

答えて

4
comp2 f g x = g (f x) 

comp2 = \f -> \g -> \x -> g (f x) 

同様

comp1 f g = g.f 

ための糖衣構文が.の定義がある

comp1 = \f -> \g -> g.f 

ための糖である。

f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion 

我々はcomp1の脱糖フォームに定義を挿入あれば、我々が得る:

comp1 = \f -> \g -> \x -> g (f x) 

これはcomp2の脱糖形と全く同じなので、明確に定義は等価です。

4

comp1 f g = g.fは、point-freeスタイルで書かれています(ポイントは参照していませんが、の値はです)。もしcomp1を呼び出すとき、二つの機能gfの組成物であるg.fに渡される3番目のパラメータは、暗黙的に存在する:(g.f) xg (f x)に等しく、すなわちgf xの結果を渡されます。 xは暗黙的に関数に渡されているため、comp1に存在しません。 (は、部分的に、それはあなたがより良い感じになり場合機能をカレー適用されるようにあなたはcomp1と考えることができます。)

comp2の型をパラメータとしてだけでなく、二つの機能、(a->b)から1と別の(b->c)を要求しますタイプaです。署名にa ->を入れる必要はありません。

2つの関数は実際には同等です。より簡潔にするために単純にHaskellのトリックを使います。

+0

ありがとう、それは今明らかです。 – 4DA

1

Currying。 MLとHaskellの複数引数の関数は、関数を返す1引数の関数の文法的な砂糖です。それが返す関数は残りの引数をとります。