1

私は Haskell を勉強していて、カリー化の概念を関数に適用する方法を理解しようとしています。カリー化は本質的に、複数の引数を持つ関数を取得し、その関数を 1 つの引数に適用し、2 番目の引数に適用される関数を返すなどの手段であることを理解しています...表現力を失うことはありません。私が取り組んでいる 1 つのチュートリアルでは、次のように尋ねています。

"のカリー化バージョンを書きます2 * (\x y -> x*y)2 3"

誰かがこれを解決する方法を教えてくれることを願っています。前もって感謝します

編集: 2 人のコメント投稿者に応えて、私は認識していることがわかります

(\x y -> x*y) :: Num a => a -> a -> a

…が私の第一歩です。関数型プログラミングに関しては、学習曲線がかなり遅いです(また、新しいSOポスターなので、私が破ったエチケットを許してください)...私の次のステップは何ですか?

編集2:@Mikhail、uncurryラムダ式の型に適用されると、(指定されたuncurry :: (a -> b -> c) -> (a,b) -> c)形式の何かが適用されることがわかります

Num a => (a,a) -> a 
4

1 に答える 1

5

カリー化とは何かについてのあなたの基本的な理解は正しいです。具体的には、たとえば次のように、引数をタプルとして受け取る関数を変換することです。

add :: (Int, Int) -> Int
add    (x, y)     =  x + y

一度に 1 つずつ引数を取る関数に変換します。

add' :: Int -> Int -> Int
add'    x      y   =  x + y

このスキームにより、現在カリー化された関数を部分適用することができます。つまり、まだすべての引数ではなく一部の引数を適用します。たとえば、

succ :: Int -> Int
succ =  add' 1

ここでadd'、最初の引数に適用し、残りの引数を期待する関数を生成します。

逆変換は uncurrying と呼ばれ、引数を「1 つずつ」受け取る関数を、その引数をタプルとして「一度に」受け取る関数に変換します。

どちらの変換も、高階関数のファミリによってキャプチャできます。つまり、バイナリ関数には

curry :: ((a, b) -> c) -> (a -> b -> c)
curry    f             =  \x y -> f (x, y)

uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry    f             =  \(x, y) -> f x y

三項関数には

curry3 :: ((a, b, c) -> d) -> (a -> b -> c -> d)
curry3    f                =  \x y z -> f (x, y, z)

uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
uncurry3    f                  =  \(x, y, z) -> f x y z

などなど。

それでは、あなたの例を見てみましょう:

2 * (\x y -> x * y) 2 3

ここでは、2 つの引数とを乗算2する関数を適用した結果をリテラルに乗算しています。ご覧のとおり、この関数はすでに「1 つずつ」引数を取ります。したがって、それはすでにカレーです。したがって、この式のカリー化されたバージョンを書くように求められた場合、チュートリアルで何を意味するのかは私には理解できません. できることは、乗算関数に「すべて一度に」引数をとらせることで、カリー化されていないバージョンを作成することです。次に、取得します(\x y -> x * y)xy(\(x, y) -> x * y)

2 * (\(x, y) -> x * y) (2, 3)

(\(x, y) -> x * y)のように書くことができることに注意してuncurry (*)ください。

2 * uncurry (*) (2, 3)

の最初のアプリケーション (または実際にはアプリケーション、複数 ;-)) もアンカリー化すると、次の結果が(*)得られます。

uncurry (*) (2, uncurry (*) (2, 3))

これがチュートリアルの演習の背後にある意図であったかどうかは疑問ですが、これがカリー化とアンカリー化についての洞察を提供してくれることを願っています.

于 2013-04-16T09:48:53.963 に答える