我正在尝试创建curry function,可以将其应用于任何函数并返回另一个,其中应用了1个参数。
我要拥有的属性:
F A); curry (f,x)= f(x);
g(a1,a2,..,aN); curry(g,x)= g2(a2,..,aN):g2(a2,.. aN)= g(x,a2,...,aN)
g.length = N => curry(g,x).length = N-1
在原型(prototype)框架中有curry的一些实现,在one blog中有讨论。但是这种实现并不好,因为它不能在仅具有一个参数(1)的函数上很好地工作,并且返回的函数'length'属性为0(3)。
对于第一个属性,有一个简单的实现:
function curry(f,x) {
if (f.length == 1) return f(x);
...
}
但是我不知道如何使用第三条规则,即可以将函数构造为内部函数,因为会有嵌套的词法环境并且可以使用f:
function curry(f,x) {
return function() { ... }
}
但是在这种情况下,我将不再能够显式设置参数。
另一方面,可以使用“new Function”语句构造函数,如下所示:
function curry(f,x) {
var args = [];
for (var i=1; i<f.length; i++) {
args.push('a'+i);
}
var sa = args.join();
return new Function(sa,"return f(x,"+sa+")");
}
但是在这种情况下,f和x将不受约束,因为将在以下位置创建匿名函数
全局词汇环境。
所以问题是:
最佳答案
Functional库实现它的方式是将传入“curry()”的参数作为要传递的第一个参数。然后,“curry”操作的函数结果将接受调用时传入的所有其他参数,并将它们添加到参数列表的末尾。它根本不用担心参数列表的长度,因为这在JavaScript中通常不是固定的东西,因此实际上没有任何意义。
因此:
var curry = myFunction.curry("Tuesday", x + y);
因此调用:
curry(100, true);
就像调用:
myFunction("Tuesday", x + y, 100, true);
函数具有另一个称为“partial()”的函数,该函数允许对参数进行更受控的替换。当您调用“partial()”时,您传入一个虚拟参数(“_”)以指示“空洞”在参数列表中的位置:
var partialFunc = myFunction.partial("Tuesday", _, 100, true, _, "banana");
这两个“_”参数意味着生成的“partialFunc”应该将传递给它的前两个参数放在参数列表中的那些插槽中:
partialFunc(x + y, "Texas");
因此就像调用:
myFunction("Tuesday", x + y, 100, true, "Texas", "banana");
我衷心建议获得该库并查看所涉及的代码。令人惊讶的简洁明了。
还有一件事:需要注意的是,由于JavaScript并不是一种惰性计算语言,因此它与诸如Haskell之类的惰性函数语言中的“curry”运算实际上并不相同。区别在于,对“curry time”中的参数进行了评估,因此将其“熟化”到了结果中。用懒惰的语言,情况有所不同。
关于javascript currying,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5273420/