假设我有一些功能:
function g(a,b,c){ return a + b + c }
我想把它变成它的“ curry ”形式(在引号中,因为它本身并不完全是 curry ):
function h(a,b,c){
switch(true){
case (a !== undefined && b !== undefined && c !== undefined):
return a + b + c
case (a !== undefined && b !== undefined && c === undefined):
return function(c){ return a + b + c }
case (a !== undefined && b == undefined && c === undefined ):
return function(b,c){
return (c === undefined) ? function(c){ return a + b + c } : a + b + c
}
default:
return h
}
}
上面的形式有我想要的部分绑定(bind)行为:
h(1) -> h(b,c)
h(1,2) -> h(c)
h(1,2,3) -> 6
h() -> h(a,b,c)
现在我想将这个过程自动化到一些通用函数 curry
中,这样给定任何未柯里化(Currying)的函数(可能还有它的参数数量),就会生成上述函数。但我不太确定如何实现它。
或者,如果可以自动创建以下表单,那也很有趣:
function f(a,b,c){
return function(a){ return function(b){ return function(c){ return a + b + c }}}
}
虽然绑定(bind) f
看起来像这样:
f(1)(2)(3) = 6
所以它非常笨拙且不合惯用,但创建上述形式对我来说似乎更可行。
现在是否可以通过某些函数生成上述任何表单,如果可以,如何生成?
最佳答案
我相信您可以简单地使用 Function.prototype.bind
.这为您提供了所需的所有灵 active ,无论您是想要立即获得函数的结果,还是只是将另一个值插入参数直到您决定执行。
function sum() {
return [].reduce.call(arguments, function (c, n) {
return c + n;
});
}
sum(1, 2); //3
var sum2 = sum.bind(null, 1, 2);
sum2(); //3
var sum3 = sum2.bind(null, 3);
sum3(); //6
您还可以使用辅助函数,例如:
function curry(fn) {
var c = curry.bind(this, fn = fn.bind.apply(fn, [this].concat([].slice.call(arguments, 1))));
c.exec = fn;
return c;
}
curry(sum, 1, 2)(3)(4, 5)(6, 7, 8).exec(); //36
这也非常灵活,因为您不必链接,您可以重复使用相同的柯里化(Currying)函数。
var sumOnePlus = curry(sum, 1);
sumOnePlus.exec(2); //3;
sumOnePlus.exec(3); //4;
关于javascript - 你如何柯里化(Currying)任意数量的任何 javascript 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19042221/