函数组合、结合律
函数组合
函数组合也叫饲养函数(compose)。
若干个纯函数、偏函数、柯里化函数组合成一个新的函数,形成数据传递,并实现一种有序执行的效果。
下面通过一个案例来看一下组合函数的作用。首先我们编写5个纯函数,分别有不同的功能。
function toUpperCase (str) {
return str.toUpperCase(str);
}
function exclaim (str) {
return str + '!';
}
function split (str) {
return str.split(str);
}
function reverse (str) {
return str.reverse();
}
function join (str) {
return str.join();
}
下面我们定义compose函数,并使用此函数。
function toUpperCase (str) {
return str.toUpperCase(str);
}
function exclaim (str) {
return str + '!';
}
function split (str) {
return str.split('');
}
function reverse (str) {
return str.reverse();
}
function join (str) {
return str.join();
}
function compose () {
var args = [].slice.call(arguments),
len = args.length - 1;
return function (x) {
var res = args[len](x);
while (len--) {
console.log(len, args, len, res);
res = args[len](res);
}
return res;
}
}
var comp = compose(join, reverse, split, toUpperCase, exclaim);
console.log(comp('HelloWolrd'));
也可以用ES6的reduce进行实现。
function compose () {
const args = Array.prototype.slice.call(arguments);
return function (x) {
return args.reduceRight((res, cb) => cb(res), x);
}
}
Pointfree
这种函数组合的方式是Pointfree编程风格的体现。Pointfree不使用所要处理的值,只合成运算过程。
Pointfree的本质就是使用一些通用的函数,组合成各种复杂运算。上层运算不需要直接操作数据,
而是通过底层函数处理。简单来说,Pointfree就是运算过程抽象化,处理一个值,但是不提到这个值。
有句英文这样说,Love means never having to say you’are sorry。
而Pointfree可以这样表述,Pointfree style means never having to say you data.
函数组合的实际应用
我们可以定义数据过滤的规则,用函数组合的方式进行数据过滤,获取我们想到的数据。
const data = [
{"id": "1","course":"ReactJS+新闻头条实战","classes":"25","is_free":"0"},
{"id": "2","course":"VueJS+美团实战","classes":"30","is_free":"1"}
]
function compose () {
const args = Array.prototype.slice.call(arguments);
return function (x) {
return args.reduceRight((res, cb) => cb(res), x);
}
}
function classesFilter (data) {
return data.classes > 20 && data;
}
function freeFilter (data) {
return data.is_free === '0' && data;
}
var arr = [],
f = null;
data.forEach(item => {
f = compose(freeFilter, classesFilter);
f(item) && arr.push(f(item));
});
console.log(arr);