curryとapplyとprototype.js
1引数
- apply(f, a) = f(a)
- curry(f)(a) = f(a)
- curry(apply)(f)(a) = f(a)
- curry(apply)は function(f){return f} =idと同等
prototype.jsのcurryはこうなっていない。と言っても対応するapplyがない以上なるならないの問題以前か。ただf.curry()がfそのままのようなので、部分適用という評価は正しいと思う。
複数引数の場合を考えてみると、
2引数(applyがタプル)
- apply(f, (a, b)) = f(a, b)
- curry(f)(a)(b) = f(a, b)
- curry(apply)(f)(a, b) = f(a, b)
2引数(applyが展開)
- apply(f, a, b) = f(a, b)
- curry(f)(a)(b) = f(a, b)
- curry(apply)(f)(a)(b) = f(a, b)
0引数(タプル)
- apply(f, ()) = f()
- curry(f)() = f()
- curry(apply)(f)() = f()
0引数(展開)
- apply(f) = f()
- curry(f) = f()
- curry(apply)(f) = f()
ECMA Scriptのapplyをそのままつかうんだとしたら
- f.apply(this, [a, b]) = this.f(a, b)
- f.curry(this)(a)(b) = this.f(a, b)
- Function.prototype.apply.curry(f)(this)(a, b) = this.f(a, b)
となるようにすべきなのかな
fが一引数の場合を考えると、第二引数は配列でなくてはいけないから
- Function.prototype.apply.curry(f)(this)([a, b]) = this.f(a, b)
になっちゃうか。つかこのapplyだと等式curry(apply)(f)=fが満たせないな。
Function.prototype.curry = function () { var args = Array.apply(null, arguments); var that = args.shift(); var func = this; return function (arg) { var nargs = Array.apply(null, args) nargs.push(arg); if (func.length == nargs.length) { return func.apply(that, nargs); } else { nargs.unshift(that); return func.curry.apply(func, nargs); } } }
結局メソッドは無視で、関数版applyを用意し、f.bind(this).curry()...として、扱うべきだろうか。
そして、f.fapply().curry()(a,b) == f(a,b)になるようなって考えたけど、このfapplyってfそのものじゃないか。じゃあ意味なしかな。