回答:
元々、カリー化は実際的なプログラミング手法ではなく、分析を単純化することでした。ラムダ計算では、すべての関数は単項です。カレーは、同様の理由で言語レベルでよく使用されます:計算モデルの単純化。
名前付きの便利な関数を、引数を修正するだけで、より一般的な別の関数として実装できる場合に、部分的なアプリケーションが使用されます。
それらは、計算のさまざまな部分を含む別個の形式のままです。考慮してください:
x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)
カリー化された関数は引数にバインドされた値を持たず、特定の順序で引数を取ります。関数をカレー化すると、結果をカレー化したり、関数が引数をとる順序を変更したりすることはありません(ただし、そうするためにアンカレーやカレー化は可能です)。対照的に、部分関数は引数にバインドされた値を持ち、残りの引数に沿ってさらに部分的に適用できます。
カリー化された関数の適用は、部分的な適用に近い(結局のところ、関数をカリー化せずにそのままにしておきます。ある時点で、適用することになります)。これは、用途が交差し始める場所です。これを行う場合、カレーは、部分的な適用に向けた2つのステップのうちの最初のステップにすぎません。
あなたの質問は次のように言い換えることができると思います:なぜ言語はカレーを持っているのですか?
それは主に利便性の問題です:
Ocamlでは、
let sum3 x y z = x + y + z;;
let foo xx yy ll = List.map (sum3 xx yy) ll;;
Schemeでは、無名関数を明示的に作成する必要があります
(define (sum3 x y z) (+ x y z))
(define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))
部分的なアプリケーションとカリー化を伴う言語では、あらゆる場所で部分的なクロージャーを作成しないように、最適化を行う必要があります。実装が常にsum3
次のように定義されているかのように適用したくない場合
let sum3 x =
fun y ->
(fun z -> x + y + z)
つまり、計算時に2つの中間クロージャーを割り当てますsum3 1 2 3
(理解され、((sum3 1) 2) 3
... として解析されます)。合計をすぐに計算する必要があります。