JavaScriptでcurry化

一昔前に流行ったネタでいろんな人がコードを書いていたと思うんだけど,3引数以上の関数をきちんとcurry化できる例 (「「「「関数を返す関数」を返す関数」を返す関数」…」に変換する) を見つけられなかったので,自分で書いてみた。

function curry(fun) {
  function c(len, arg) {
    if (len == 0)
      return fun.apply(null, arg);
    return function(x) {
      return c(len-1, arg.concat(x));
    };
  }
  return c(fun.length, []);
}

curry(function(x, y, z, w){ return x + y + z + w; })('a')('b')('c')('d'); // => 'abcd'

1度に2つ以上の引数を与えられるようにするなら以下のように書き換える。

function curry2(fun) {
  function c(len, arg) {
    if (len <= 0)
      return fun.apply(null, arg);
    return function() {
      return c(len-arguments.length,
               arg.concat(Array.prototype.slice.call(arguments)));
    };
  }
  return c(fun.length, []);
}

curry2(function(x, y, z, w, v){ return x + y + z + w + v; })('a')('b', 'c')('d')('e'); // => 'abcde'