Javascript 咖喱功能到底应该如何工作?

Javascript 咖喱功能到底应该如何工作?,javascript,currying,Javascript,Currying,我的函数如下所示: function curry(fn) { var args = [].slice.call(arguments, 1); return function() { return fn.call(this, args.concat([].slice.call(arguments))); }; } function curry(fn) { var args = []; return function curring() {

我的函数如下所示:

function curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.call(this, args.concat([].slice.call(arguments)));
    };
}
function curry(fn) {
    var args = [];
    return function curring() {
        args = args.concat([].slice.call(arguments));
        if (args.length >= fn.length) {
            return fn.apply(this, args);
        } else {
            return curring;
        }
    };
}
我一直认为这就是函数的外观和工作原理:

function add(a, b, c, d) {
   return a+b+c+d;
}


curry(add, 1, 2)(3, 4);
但是他说

它可以被称为一系列函数,每个函数都有一个参数

所以咖喱应该是这样的:

function curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.call(this, args.concat([].slice.call(arguments)));
    };
}
function curry(fn) {
    var args = [];
    return function curring() {
        args = args.concat([].slice.call(arguments));
        if (args.length >= fn.length) {
            return fn.apply(this, args);
        } else {
            return curring;
        }
    };
}
并被用作:

function add(a, b, c, d) {
   return a+b+c+d;
}

curry(add)(1)(2)(3)(4);

我说得对吗?

严格地说,curry将一个具有多个参数的函数转换为一系列具有单个参数的函数,就像在第二个
curry
函数中一样:

  • 如果调用所有函数(在链中),则得到函数的完整应用程序,从而产生与原始函数相同的结果:
    curry(add)(1)(2)(3)(4)
    返回与
    add(1,2,3,4)
    相同的值,即
    10

  • 如果只调用子集,则会得到一个部分应用的函数:

  • addOne=curry(add)(1)
  • addOneAndTwo=addOne(2)
  • addOneAndTwo(3)(4)
    返回
    10
在Javascript中,curry通常用作部分应用程序的同义词,就像在第一个
curry
函数中一样。释义:

curry将参数咖喱化(烧入)到函数中,返回一个新函数,当调用该函数时,将原始参数(连同任何新参数)传入

有关详细说明,请参阅

下面是Evan Borden的一个工作实现

一些注意事项:

  • 在第一个函数中,
    fn.call
    是错误的。必须使用
    fn.apply
    ,因为作为第二个参数传递的数组必须用作参数列表,并且
    call
    仅将其视为一个参数

  • 第二个函数生成一个只能调用1次的curry函数,因为每个调用的
    curring
    实例修改捕获的
    args
    数组,该数组在调用
    curry
    时初始化

    例如:

  • addOne=curry(add)(1)
    使用自己的
    参数定义
    addOne
    ,并将其初始化为
    [1]

  • addOne(2)(3)(4)
    返回
    10
    并将
    args
    修改为
    [1,2,3,4]

  • addOne(2)(3)(4)
    (第二次)失败,原因是
    addOne(…)不是一个函数,
    addOne(2)
    尝试调用
    add(1,2,3,4,2)


我认为它们都是正确的。但是根据约翰·雷斯格在《javascript忍者的秘密》中的说法,第一种方法是正确的。@AhmadF为什么会这样?第一个返回一个函数,然后返回结果,第二个继续返回函数,直到列表或参数与函数参数的数量相同。我猜
函数add(a,b,c,d)
必须返回
a+b+c+d
,而不是
a+b+c+c
。第一个问题只是它应该应用的一个输入错误,但是第二个是错误,谢谢你指出。