一般的に、カレーとは、2つの引数の関数を、1つの引数を取り、別の1つの引数の関数を返す関数に変換することを意味します。したがって、最初の引数でカレー関数を呼び出し、次に2番目の引数でこれを呼び出した結果は同等です。両方の引数を使用して元の(カレーなしの)関数を呼び出すこと。クロージャと動的型付け(または型推論)を備えた疑似C言語では、これは次のようになります。
// The original, uncurried function:
function f(a, b) { return 2 * a - b; }
// The curried function:
function g(a) {
return function(b) {
return f(a, b);
}
}
// Now we can either call f directly:
printf("%i\n", f(23, 42));
// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));
複数回カリー化することで、マルチ引数関数をネストされた1引数関数のセットに減らすことができます。
Haskellでは、すべての関数は単一引数です。のような構成は、実際には架空のC-with-closuresとf a b c
同等です。((f(a))(b))(c)
関数に複数の引数を実際に渡す唯一の方法は、タプルを使用することです。たとえば、f (a, b, c)
-しかし、カレー関数の構文はより単純で、セマンティクスはより柔軟であるため、このオプションはめったに使用されません。
Haskell Preludeは2つの関数を定義しcurry
、uncurry
これら2つの表現の間で変換します。curry
は型です。つまり、タプルを取り、を返す((a,b) -> c) -> a -> b -> c
1つの引数の関数を取り、それを型の関数、つまり関数に変換します。を取り、aを取り、を返す関数を返します。逆を行います。(a, b)
c
a -> b -> c
a
b
c
uncurry
部分適用は実際には問題ではありません。f a b
これは、カリー化された関数(eg )があり、チェーン全体を完全に展開する代わりに(eg、f 23 42
)、途中で停止し、結果の関数をさらに渡すという状況に付けられた名前let g = f 23
です。関数を部分適用するには、カレーする必要があります(部分適用はできませんf (a, b)
)let g = f (a)
が、Haskellでは関数をカレーで書くことがデフォルトであるため、部分適用は簡単で一般的な方法です。