在javascript中解决n个参数的curried函数

时间:2016-07-29 10:52:31

标签: javascript functional-programming currying

如果f :: a - > b - > c是curry然后uncurry(f)可以定义为:

uncurry ::(a - > b - > c) - > ((a,b) - > c)

我正在尝试在javascript中实现上述功能。我的下面的实现是否正确和通用,还是有更好的解决方案?

const uncurry = f => {
  if (typeof f != "function" || f.length == 0)
    return f;

  return function()
  {     
    for (let i = 0; i < arguments.length; i++){
      f = f(arguments[i]);
    }

    return f;
  };
}


const curry = f => a => b => f(a, b);
const curriedSum = curry((num1, num2) => num1 + num2);
console.log(curriedSum(2)(3)); //5

console.log(uncurry(curriedSum)(2, 3)); //5

2 个答案:

答案 0 :(得分:2)

您的uncurry有三个问题:

  1. 如果不是所有预期的参数都被传递,它将返回一个curried函数(这不是正常的,未发生的函数的行为)
  2. 它无法处理不必要的论点
  3. 由于您不重复使用任何内容,因此实施功能不是很有用
  4. 这是一种更实用的方法:

    &#13;
    &#13;
    const id = x => x;
    const uncurry = f => (x, y) => f(x)(y);
    
    const uncurryn = n => f => (...xs) => {
      const next = acc => xs => xs.reduce(uncurry(id), acc);
      if (n > xs.length) throw new RangeError("too few arguments");
      return next(f) (xs.slice(0, n));
    }
    
    const sum = x => y => z => x + y + z;
    
    try {uncurryn(3)(sum)(1, 2)} catch(e) {console.log(e.message)}
    console.log(uncurryn(3)(sum)(1, 2, 3));
    console.log(uncurryn(3)(sum)(1, 2, 3, 4));
    &#13;
    &#13;
    &#13;

    uncurryn忽略不必要的参数,就像Javascript中的任何其他函数一样。它重复使用uncurryreduceid

    如果传递的参数太少,则会抛出错误,因为在每种情况下都不清楚,应该返回哪个值(NaNundefined)。

答案 1 :(得分:1)

这不错,但你假设f是循环遍历所有参数的函数。

此外,如果您使用的是es6,请考虑使用rest运算符而不是arguments。并且for ... of是es6中用于循环遍历数组值的更好语法。

&#13;
&#13;
const uncurry = f => {
  if (typeof f !== "function" || f.length == 0)
    return f;

  return (...args) => {     
    for (let arg of args) {
      if (typeof f !== "function") {
        return f;
      }
      
      f = f(arg);
    }

    return f;
  };
}




const curry = f => a => b => f(a, b);
const curriedSum = curry((num1, num2) => num1 + num2);
console.log(curriedSum(2)(3)); //5

console.log(uncurry(curriedSum)(2, 3)); //5
&#13;
&#13;
&#13;