咖喱功能应该如何运作?

时间:2013-08-25 16:59:32

标签: javascript currying

我的功能看起来像这样:

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

但是Wikipedia Article

  

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

所以咖喱应该是这样的:

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

我是对的吗?

1 个答案:

答案 0 :(得分:2)

严格地说, currying 将具有多个参数的函数转换为一系列函数,每个函数都有一个参数,如第二个{​​{1}}函数所示: / p>

  • 如果您调用所有这些(链中),您将获得该函数的完整应用程序,该函数产生与原始函数相同的结果:
    curry返回与curry(add)(1)(2)(3)(4)相同的内容,即add(1, 2, 3, 4)

  • 如果您只调用一个子集,则会获得部分应用的功能:

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

在Javascript中, currying 通常用作部分应用程序的同义词,就像在您的第一个10函数中一样。释义Prototype documentation

  

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

有关详细说明,请参阅What is the difference between currying and partial application

以下是 Evan Borden true curry function in javascript的有效实施。

一些警告:

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

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

    例如:

    1. curry定义addOne = curry(add)(1);,其addOne已初始化为args

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

    3. [1, 2, 3, 4](第二次)失败,addOne(2)(3)(4)
      addOne(...) is not a function尝试拨打addOne(2)