函数式编程

科里化函数

科里化的关键是返回函数实现连式调用、参数收集、以及判断收集结束做最终调用。判断收集结束有很多办法:对比实参和形参的长度;判断实参的个数是否为 0(不传)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function currying(fn) {
return (...args) => {
if (args.length === 0) { // 通过手动调用的方式(即不传参数)来判断收集结束
return fn(...args);
}
return currying(fn.bind(null, ...args));
}
}

function add(...args) {
return args.reduce((total, num) => {
return total + num;
}, 0);
}

add = currying(add);

// 须手动结束调用
var result = add(1)(20)(3)(4)(6, 2)();
console.log(result);

上面版本中,对被科里化的函数没要求,但需要手动结束调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function currying(fn) {
return function _fn(...args) {
if (args.length >= fn.length) { // 这里通过型参长度来判断是否要调用,所以 add 的参数不能使用 spread 运算符 ...
return fn(...args);
}

return (...remain) => {
return _fn(...args, ...remain);
};
};
}

// 这个版本中,被科里化函数的形参长度必须固定
function add(a, b, c, d) {
return a + b + c + d;
}

var add = currying(add);

var result = add(1)(20)(3)(4);
console.log(result);

这个版本中,不需手动结束调用,但被科里化的函数的形参必须要有长度。