カリー化と部分適用は違いがよくわからなかったので調べてみました。
Wikipedia によればカリー化とは・・・
複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。
引数の適用までは行わないそうです。
JavaScript で実装するとすると以下のような感じでしょうか。
Function.prototype.curry = function (context) {
var func = this;
var slice = Array.prototype.slice;
return function partial() {
var args = slice.call(arguments);
if (args.length >= func.length) {
return func.apply(context, args);
} else {
return function () {
var argArray = slice.call(arguments);
return partial.apply(context, args.concat(argArray));
};
}
}
};
これでカリー化できます。
function sum(a, b, c) {
console.log(a + b + c);
}
sum.curry()(1)(2)(3);
// 6
context 付きでも。
var greeter = {
greeting: 'Hey,',
greet: function (adj, noun) {
console.log(this.greeting, adj, noun);
}
};
greeter.greet.curry(greeter)('pretty')('girl');
// Hey, pretty girl
ただしこれだと部分適用時に、Function.prototype.bind
を使ったときのように length
が減っていかないのが残念です。
console.log(sum.length);
// 3
console.log(sum.bind(null, 1).length);
// 2
console.log(sum.curry().length);
// 0
console.log(sum.curry()(1).length);
// 0
何かうまい方法はないんでしょうか?