今天在群里聊天,有人发了一道面试题:
1 2 3 4
| add(1).value add(1)(2).value add(1)(2)(3).value
|
我第一个想法是 curry。但是网上都是这样的
1 2 3 4 5 6 7 8 9 10 11 12
| var add = function(a) { var sum = a; var addMore = function(b) { sum += b; return addMore; }; addMore.toString = function() { return sum; }; return addMore; }; add(1)(2)(3)(4);
|
这只是简单的累加。但是我在 nodejs 的环境里是没办法想这样调用得到结果的。需要手动去调用一次toString()
。
幸好这道面试题是用一个value
返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
function add(a) { sum.i = 1; function sum(b) { sum.value += b * (++sum.i); return sum; } sum.value = a; return sum; }
console.log(add(1).value); console.log(add(1)(2).value); console.log(add(1)(2)(3).value);
|
等等,这道题好像还有个问题,如果是 $value^2$ 的和呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
function add(a) { sum.value = a ** 2; function sum(b) { sum.value += b ** 2; return sum; } return sum; } console.log(add(1).value); console.log(add(1)(2).value); console.log(add(1)(2)(3).value);
|
但是如果我使用下面的方法,就不能保证每次运行都是相同的值了
1 2 3 4
| const h = add(2); console.log(h(3).value);
console.log(h(3).value);
|
所以改成这样
1 2 3 4 5 6 7 8 9 10 11 12 13
| function reducer(a, f) { return Object.assign(b => reducer(f(a, b), f), { value: a }); }
const add = reducer(0, (a, b) => a + b ** 2);
console.log(add(2)); console.log(add(1)(2).value); console.log(add(1)(2)(3).value);
const h = add(2); console.log(h(3).value);
|