1

我的功能如下所示:

function curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.call(this, args.concat([].slice.call(arguments)));
    };
}

我一直认为函数应该是这样的,并且应该像这样工作:

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


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

维基百科文章

它可以作为一个函数链调用,每个函数都有一个参数

所以咖喱应该是这样的:

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);

我对吗?

4

1 回答 1

2

严格来说,currying将具有许多参数的函数转换为一系列函数,每个函数都有一个参数,如您的第二个curry函数:

  • 如果你调用所有它们(链中),你会得到函数的完整应用,它产生与原始函数相同的结果:
    curry(add)(1)(2)(3)(4)返回与 相同add(1, 2, 3, 4),即10

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

    1. addOne = curry(add)(1);
    2. addOneAndTwo = addOne(2);
    3. addOneAndTwo(3)(4)返回10

在 Javascript 中,currying通常用作部分应用程序的同义词,就像在您的第一个curry函数中一样。解释原型文档

curry curry (burns in) 函数的参数,返回一个新函数,调用该函数时调用原始传递的 curried 参数(以及任何新参数)。

有关更详细的说明,请参阅柯里化和部分应用之间的区别

这是Evan Borden在 javascript中的一个真正的咖喱函数的工作实现。

一些警告:

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

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

    例如:

    1. addOne = curry(add)(1);addOne用自己的args初始化定义为[1]

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

    3. addOne(2)(3)(4) (第二次)失败addOne(...) is not a function,尝试调用
      addOne(2)add(1, 2, 3, 4, 2)

于 2013-08-25T21:34:38.300 回答