LoginSignup
21
27

More than 5 years have passed since last update.

JavaScript でカリー化

Last updated at Posted at 2013-01-19

カリー化と部分適用は違いがよくわからなかったので調べてみました。

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

何かうまい方法はないんでしょうか?

21
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
27