核心提示:函数的合成如果一个值要经过多个函数,才能变成另一个值,可以把中间步骤合并成一个函数,这叫做函数的合成上图中,X和Y之间的变形关系是函数f,Y和Z之间的变形关系是函数g,那么X和Z之间的关系,就是g和f...
函数的合成
如果一个值要经过多个函数,才能变成另一个值,可以把中间步骤合并成一个函数,这叫做函数的合成
上图中,X和Y之间的变形关系是函数f,Y和Z之间的变形关系是函数g,那么X和Z之间的关系,就是g和f的合成函数g·f。
const compose = function(f, g){ return function(x){ return f(g(x)) } }
函数的合成还必须满足结合率
compose(f, compose(g, h)); // 等同于 compose(compose(f, g), h); // 等同于 compose(f, g, h)
合成也是函数必须是纯的一个原因。因为一个不纯的函数,怎么跟其他函数合成?怎么保证各种合成以后,它会达到预期的行为?
前面说过,函数就像数据的管道(pipe)。那么,函数合成就是将这些管道连了起来,让数据一口气从多个管道中穿过。
柯里化
f(x)和g(x)合成为f(g(x)),有一个隐藏的前提,就是f和g都只能接收一个参数,如果可以接收多个参数,比如f(x, y)和g(a, b, c),函数合成就会非常麻烦
这时就需要函数柯里化了。所谓”柯里化”,就是把一个多参数的函数,转化为单参数函数。
function add(x, y){ return x + y; } add(1, 2) // 3 function Add(x){ // 对第一个参数没有进行处理,只是返回的函数中通过闭包拿到参数值 return function(y){ return x + y; } } Add(1)(2)
有了柯里化以后,我们就能做到,所有函数只接受一个参数。后文的内容除非另有说明,都默认函数只有一个参数,就是所要处理的那个值。
函子
函数不仅可以用于同一个范畴之中值的转换,还可以用于将一个范畴转成另一个范畴。这就涉及到了函子(Functor)
函子是函数式编程里面最重要的数据类型,也是基本的运算单位和功能单位。
它首先是一种范畴,也就是说,是一个容器,包含了值和变形关系。比较特殊的是,它的变形关系可以依次作用于每一个值,将当前容器变形成另一个容器。
可以理解为值是输入的一组参数,变形关系是参数处理逻辑,函子将他们转化为另一组新数据。一般约定,函子的标志就是容器具有map方法。该方法将容器里面的每一个值,映射到另一个容器。学习函数式编程,实际上就是学习函子的各种运算。
接下来的原文太过理论化,等以后加深理解再补充