什么是 Monad
Monad (n.)
- 用普通语言解释,Monad 是一种类型无关的符合特定行为的抽象结构。
- 用编程语言解释,Monad 是一个类型类(元类)。
-
用数学语言解释,Monad 是自函子范畴上的一个幺半群。
- 映射的抽象
-
类型的抽象
- 串联
- 注入
Monad 是一种 Functor。
预备知识
- 范畴论
- 函子
- 态射
Monadic (adj.)
“Monadic” 仅仅表示 “和 Monad 相关的”。一个 monadic 类型就是一个 Monad 类型类的实例;一个 monadic 值就是一个具有 monadic 类型的值。
当我们说某个东西 “是一个 monad” 的时候,我们其实表达的意思是“这个类型是 Monad 这个类型类的实例”;作为 Monad 的实例就有三要素:类型构造器,注入函数,串联函数。1
JS 的 Promise 实际上是一种 Monad
跟 Either Monad 有点像,要么是 Fulfilled 状态(Right 值),要么是 Rejected 状态(Left 值),只不过在这之前是 Pending 状态。
factorial(5) 与 120
有些语言不使用 return 关键字来返回函数值:因为一个函数就是一个单独的表达式(expression),而不是一组陈述(statement),求值表达式所得的结果就是函数的返回值。
所以这就是函数式编程与命令式编程的区别。
暗箱,隐藏细节
当看见一个参数化类型(parameterized type)时,这表示代码并不在乎实际的类型是什么。另外,我们还可以给出一个更强的陈述:没有办法知道参数化类型的实际类型是什么,也不能操作这种类型的值;不能创建这种类型的值,也不能对这种类型的值进行探查(inspect)。
参数化类型唯一能做的事,就是作为一个完全抽象的 “黑箱” 而存在。2
Just 是对任意类型的装箱。
Nothing 是对空的装箱。你不必每次自己去判断函数返回值是否为 null,这个判断是在暗箱里进行的(对开发者透明)。
你关注的是有值的情况。
除法函数,a/b
当分母 b 为 0 时,这个函数应该如何?
a convenient alternative to exceptions
Maybe 类型
Maybe 是一种 Monad。
Haskell 对于 Maybe 的定义是 data Maybe a = Nothing | Just a
。
但为何不能是 data Maybe a = Nothing | a
呢? 以数学角度来解释,Maybe 这个范畴的定义就不准确了,因为 a 可以为任何类型。而 Nothing|Just 是固定类型的。 以程序角度来解释,不用 a
而用 Just a
是为了配合 Functor 统一处理,要不然层次上就差了一层。