javascript currying

qni*_*kst 8 javascript lexical-closures

我正在尝试创建可应用于任何函数的curry函数,并返回另一个函数,并应用了1个参数.我想要的属性:

  1. 如果函数只有一个参数curry函数应该返回值:f(a); 咖喱(f,x)= f(x);
  2. 如果函数有很多参数,则应该重新计算curried函数:g(a1,a2,..,aN); 咖喱(g,x)= g2(a2,..,aN):g2(a2,.. aN)= g(x,a2,...,aN)
  3. 咖喱功能的长度应该"根据需要"工作g.length = N =>咖喱(g,x).长度= N-1

Prototype Framework中有一些咖喱实现,并在一个博客中进行讨论.但是这个实现并不好,因为它对只有一个参数(1)的函数不起作用,并且返回函数'length'属性为0(3).

对于第一个属性,有一个简单的实现:

 function curry(f,x) {
    if (f.length == 1) return f(x);
    ...
 }
Run Code Online (Sandbox Code Playgroud)

但是我不知道如何使用第3个规则,即函数可以被构造为内部函数,因为将有一个嵌套的词法环境并且能够使用f:

function curry(f,x) {
   return function() { ... }
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我将不再能够显式设置参数.另一方面,函数可以使用'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+")");
 }
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,f和x将解除绑定,因为将在Global Lexical Environment中创建匿名函数.

所以问题:

  1. 有没有办法在用函数关键字创建函数时显式设置参数计数?
  2. 有没有办法设置用'new Function'语句创建的函数的环境?
  3. 我们有办法以任何其他方式解决我的问题吗?

Poi*_*nty 6

该方式的功能库实现它是采取传入的参数为"咖喱()"作为第一个参数传递.然后,"curry"操作的函数结果将获取调用时传入的任何其他参数,并将它们添加到参数列表的末尾.它根本不担心参数列表的长度,因为这在JavaScript中并不是一个固定的东西,所以实际上没有意义.

从而:

var curry = myFunction.curry("Tuesday", x + y);
Run Code Online (Sandbox Code Playgroud)

所以打电话:

curry(100, true);
Run Code Online (Sandbox Code Playgroud)

就像打电话一样:

myFunction("Tuesday", x + y, 100, true);
Run Code Online (Sandbox Code Playgroud)

Functional具有另一个称为"partial()"的函数,它允许更加受控的参数替换.当你调用"partial()"时,你传入一个伪参数("_")来指示参数列表中"孔"的位置:

var partialFunc = myFunction.partial("Tuesday", _, 100, true, _, "banana");
Run Code Online (Sandbox Code Playgroud)

这两个"_"参数意味着生成的"partialFunc"应该将传递给它的前两个参数放入参数列表中的那些插槽中:

partialFunc(x + y, "Texas");
Run Code Online (Sandbox Code Playgroud)

因此就像打电话:

myFunction("Tuesday", x + y, 100, true, "Texas", "banana");
Run Code Online (Sandbox Code Playgroud)

我衷心地建议获取该库并查看所涉及的代码.它令人惊讶地简洁明了.

还有一两件事:需要注意的是,因为JavaScript并不是一个懒惰的评价语言,这不是很重要真的一样象Haskell懒功能语言的"咖喱"操作.区别在于评估 "咖喱时间"的论点,因此将其"熟化"到结果中.在懒惰的语言中,事情是不同的.