Javascript的函数式编程术语解释之二

上页

  前面解释了组合数学的相关术语,这里解释一些范畴Category相关术语。

值Value

任何复杂或原始值都是用于计算的,在函数编程中值总是不可变的。像Functor或Monad之类都是包含值的结构,因此它们彼此是可以嵌入的。

 

Constant不变量

这是指向一个值的不变性引用,不要和Variable混淆,后者是指向一个值会在任何时候被修改指向另外一个值的,是可变的。

const five = 5  
const john = {name: 'John', age: 30}

不变量是引用透明的,意味着它们会被它们代表的值替换却丝毫不影响结果,换句话说,上面两个不变量写为如下:

john.age + five === ({name: 'John', age: 30}).age + (5)

这条语句返回总是true。

 

Functor函子

一个带有map函数的对象且遵循一定的规则,Map是作为一个对象中基于值的一个函数然后返回一个对象,简单函子使用Javascript是数组案例:

[2,3,4].map( n => n * 2 ); // [4,6,8]

n*2这个算法对数组中每个元素都计算了一遍,如同我们使用for循环打开这个数组,逐个遍历,逐个应用n*2这个算法进行计算一样,而在函数编程中只要使用map就可以了,让func称为实现map函数的一个对象,f 或g为任意函数,如果func的map函数遵循下面规则,那么func称为函子。

func.map(x => x) == func

以及

func.map(x => f(g(x))) == func.map(g).map(f)

第一个条件比较清楚,map完成的类型还是func这个类型,后面条件是映射一个f(g(x))组合拆解为每个函数分别映射map。

按照上面的定义数组array是一个函子,因为它这两个条件都满足:

[1, 2, 3].map(x => x); // = [1, 2, 3]

let f = x => x + 1;
let g = x => x * 2;
      
[1, 2, 3].map(x => f(g(x))); // = [3, 5, 7] 
[1, 2, 3].map(g).map(f);     // = [3, 5, 7] 

 

引用透明Referential Transparency

一个表达式能够被它的值替换,丝毫不会影响程序的任何行为,这种表达式称为引用透明。

let greet = () => "Hello World!";

任何对greet()调用都能被"Hello World"替换,因此greet是引用透明

 

Monoid

是一种带有一些数据类型和两个参数的函数,这两个参数是结合两个值,存在一个identity(单元)值 不会影响函数的结果。

最简单的monoid是数字和加法:

1 + 1; // 2

数据类型是number,函数是+,number的identity(单元)值是0,因此,将0加到任何数字number都不会改变结果:

1 + 0; // 1

对于要成为monoid,也需要一组操作不会影响结果:

1 + (2 + 3) == (1 + 2) + 3; // true

数组进行相关操作也是一个monoid:

[1, 2].concat([3, 4]); // [1, 2, 3, 4]

数组的identity(单元/享元)值是是空数组[]

[1, 2].concat([]); // [1, 2]

函数也可以通过正常函数组合作为一个操作形成一个monoid,输出类型是其输入类型:

(a) => a

 

Monad

一个Monad是一个带有of和chain函数的对象:

['cat,dog ','fish,bird '].chain(a => a.split(', ')) // ['cat','dog','fish','bird'] 
      
//Contrast to map 
['cat,dog ','fish,bird '].map(a => a.split(', ')) // [['cat','dog'], ['fish','bird']] 

这里chain类似函子的map,唯一区别是chain不会将嵌套对象进行分解或者称反嵌套,而map则可以,可见上面函子段落。

这里的of类似return,而chain类似bind(不是javascript的bind/call),一般Haskell或F#都会提供Monad的构建,而Javascript这方面比较弱。

 

什么是Monad

函数编程中functor和monad的形象解释

monad专题

Javascript专题

函数编程专题