定义

函数组合又称 “饲养函数”。
是若干个纯函数、是若干个纯函数、、柯里化函数组合成一个新的函数、形成数据传递、并实现一种有序执行的效果。
定义一个函数compose用于处理函数的组合。

例子

基础版

只能组合两个函数

  1. // 字符串转大写
  2. function toUpperCase(str){
  3. return str.toUpperCase();
  4. }
  5. // 增加感叹号
  6. function exclaim(str){
  7. return str + '!';
  8. }
  9. function compose(f, g){
  10. return function(x){
  11. return f(g(x)); //左倾 自右向左依次执行
  12. }
  13. }
  14. // x是通过f, g之间的“管道”传输值
  15. var f = compose(exclaim, toUpperCase);
  16. console.log(f('hello')); //HELLO!

增强版

借助arguments就能够组合多个函数

  1. function toUpperCase(str){
  2. return str.toUpperCase();
  3. }
  4. function exclaim(str){
  5. return str + '!';
  6. }
  7. function split(arr){
  8. return arr.split('');
  9. }
  10. function reverse(str){
  11. return str.reverse();
  12. }
  13. function join(str){
  14. return str.join('-');
  15. }
  16. function compose(){
  17. var args = Array.prototype.slice.call(arguments), // 把arguments转为数组
  18. len = args.length - 1;
  19. return function(x){
  20. var res = args[len](x);
  21. while(len --){
  22. res = args[len](res);
  23. }
  24. return res;
  25. }
  26. }
  27. // 执行的方向是由右至左依次执行
  28. var f = compose(join, reverse, splite, exclaim, toUpperCase);
  29. console.log(f('hello')); // !-O-L-L-E-H

最终方案

使用reduceRight也能做到compose

  1. function compose(){
  2. return (x) => [].slice.call(arguments).reduceRight((res, cb) => cb(res), x);
  3. }

结合律 Associativity

在组合函数的参数中,再进行分组,函数的分组组合和原来的组合所得出的结果是一样的。
与数字中的结合律表现是一致的。

  1. var f = compose(join, reverse, split);
  2. var f2 = compose(compose(join, reverse), split);
  3. var f3 = compose(join, compose(reverse, split));
  4. console.log(f('hello')); //o-l-l-e-h
  5. console.log(f2('hello')); //o-l-l-e-h
  6. console.log(f3('hello')); //o-l-l-e-h

point-free

一种编程风格,我们可以把数据处理的过程定义与数据无关的合成运算,不需要用到代表数据的哪个参数
只需要把运算步骤合成到一起,在使用这种模式之前需要定义一些辅助的基本运算函数。

  1. 不需要指明处理的数据
  2. 只需要合成运算过程
  3. 需要定义一些辅助的基本运算函数

    Love means never having to say you’re sorry. Excuse me.

Pointfree style means never having to say your data.