1. ホーム
  2. language-agnostic

[解決済み] キュアリングと部分適用の違いは何ですか?

2022-03-22 07:37:47

質問

インターネット上で、「他の人がやっているカレーはカレーではない、部分的にやっているだけだ」という意見をよく見かけますが、これはどういうことですか?

部分適用とは何か、カレーとどう違うのか、まともな解説がない。あるところでは同等の例をカレーと表現し、別のところでは部分適用と表現するなど、一般的に混乱があるようです。

どなたか、両者の定義と、その違いについて詳しく教えてください。

どのように解決するのですか?

の単体関数を変換することです。 n 引数を n 関数の引数を1つずつにしたものです。次のような関数があるとする。

function f(x,y,z) { z(x(y));}

カレーにすると、なる。

function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }

f(x,y,z)の完全な応用を得るには、こうする必要があります。

f(x)(y)(z);

多くの関数型言語では f x y z . を呼び出すだけなら f x y または f(x)(y) のクロージャであり、部分的に適用された関数となります。 lambda(z){z(x(y))} にxとyの値を渡し、それを f(x,y) .

部分適用を使用する方法の1つは、次のように関数を一般化された関数の部分適用として定義することです。 折り :

function fold(combineFunction, accumulator, list) {/* ... */}
function sum     = curry(fold)(lambda(accum,e){e+accum}))(0);
function length  = curry(fold)(lambda(accum,_){1+accum})(empty-list);
function reverse = curry(fold)(lambda(accum,e){concat(e,accum)})(empty-list);

/* ... */
@list = [1, 2, 3, 4]
sum(list) //returns 10
@f = fold(lambda(accum,e){e+accum}) //f = lambda(accumulator,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list)  //returns 10