动态柯里化,以及如何在 JavaScript 变量中同时保存函数和值
Dynamic currying, and how to hold both a function and value in JavaScript variable
我正在学习 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
我假设涉及柯里化,并且我认为我基本了解柯里化如何以类似
的简单形式工作
a=>b=>c=> a+b+c
但我不知道如何创建一个能够处理不确定数量的输入的柯里化函数,也不知道如何使它产生一个既可以作为值又可以作为函数的变量.
如有任何见解,我们将不胜感激!我只需要朝着正确的方向推动——在这一点上,我什至不知道我在寻找什么。
如评论中所述,您不能定义同时充当数字和函数的变量。
要柯里化可变函数,您必须显式传递元数:
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 的有趣教程。这是一个深入的话题。
这里的技巧是您需要定义 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
对于柯里化,您只想使 res()
也 return 成为 valueAndCallable
。
我正在学习 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
我假设涉及柯里化,并且我认为我基本了解柯里化如何以类似
的简单形式工作a=>b=>c=> a+b+c
但我不知道如何创建一个能够处理不确定数量的输入的柯里化函数,也不知道如何使它产生一个既可以作为值又可以作为函数的变量.
如有任何见解,我们将不胜感激!我只需要朝着正确的方向推动——在这一点上,我什至不知道我在寻找什么。
如评论中所述,您不能定义同时充当数字和函数的变量。
要柯里化可变函数,您必须显式传递元数:
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 的有趣教程。这是一个深入的话题。
这里的技巧是您需要定义 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
对于柯里化,您只想使 res()
也 return 成为 valueAndCallable
。