首页 文章

动态currying,以及如何在JavaScript变量中保存函数和值[重复]

提问于
浏览
6

这个问题在这里已有答案:

我正在学习JavaScript,最近我遇到了一个practice problem,它要求我构建一个可以创建输出的函数,如下所示:

var threeSum= sum(3);
threeSum //3
threeSum(4) //7
threeSum(4)(3) //10
threeSum(4)(3)(7) //17
threeSum(4)(3)(7)()(2) //19
threeSum - 2 //1
threeSum + 2 //5

我认为涉及到currying,我认为我已经基本掌握了curry如何以简单的形式工作

a=>b=>c=> a+b+c

但我不知道如何创建一个能够处理不确定数量的输入的curried函数,也不知道如何使它成为一个可以作为值和函数的变量 .

任何见解都表示赞赏!我只需要朝着正确的方向努力 - 此时我甚至不知道我在寻找什么 .

2 回答

  • 4

    这里的诀窍是你需要定义valueOf,它允许javascript将对象(如函数)解释为值:

    var valueAndCallable = function(x) {
        var res = function(a) { return a + x };
        res.valueOf = function() { return x; };
        return res;
    };
    
    var v = valueAndCallable(1)
    console.log(v);      // function ... -
    console.log(+v);     // 1 - calls .valueOf()
    console.log(1 + v);  // 2 - calls .valueOf()
    console.log(v(3));   // 4
    

    对于currying,你只想让 res() 也返回 valueAndCallable .

  • 1

    如评论中所述,您无法定义同时充当数字和函数的变量 .

    要理解可变参数函数,您必须明确地传递arity:

    const curryN = n => f => {
      let next = (m, acc) => x => m > 1 ? next(m - 1, acc.concat([x])) : f(...acc, x);
      return next(n, []);
    };
    
    const sum = (...args) => args.reduce((acc, x) => acc + x, 0);
    
    sum(1, 2, 3, 4, 5); // 15
    curryN(5)(sum)(1)(2)(3)(4)(5); // 15
    
    let sum3 = curryN(3)(sum);
    sum3(1)(2)(3); // 6
    
    let sum5plusX = curryN(2)(sum)(5);
    sum5plusX(6); // 11
    

    我建议不要使用可变参数函数 . 请改用 Array.reduce . 这是一个关于currying的有趣教程 . 这是一个深入的话题 .

相关问题