Haskell 中的Monad 小记
monad基本上可以解释为实现了lift,bind操作的类型类。具体解释可以参考wikipidia上的定义
Monad构成自三个部份:
- 类型构造子 m m m,建造一个Monad类型 m T m\space\space T m T
- 类型转换子,经常叫做unit或return,将一个对象x嵌入到Monad中:
unit(x) :: x -> Monad x
- 组合子,典型的叫做bind(约束变量的那个bind),并表示为中缀算子(>>=),去包装一个Monad变量,接着把它插入到一个Monad函数/表达式之中,结果为一个新的Monad:
(>>=) :: forall a b. m a -> (a -> m b) -> m b
1. 解释 (>>=)
(>>=) 是一个二元运算符,它接受两个参数,一个参数是一个Monad(m a),一个参数是一个function(a -> m b).这个function接受的是一个a,返回是一个Monad(m b)
这个运算符做的事情可以理解为,将第一个参数(m a)解包,解出a,按照第二个参数,及那个函数指定的方法得到新的Monad,即(m b)
可以将其理解成 拆解 && 连接
看一个例子
这个例子来源于一个Monad 叫做Maybe.
add mx my = mx >>= λx -> (my >>= λy -> Just (x + y))
λ代表的是匿名函数.Just是Maybe类型的其中一个值构造器。
通过解释上边的例子,可以理解>>=这个运算符
mx解包成x,带入后边的匿名函数中。后边的匿名函数需要输入一个my.然后将y解包,组合x + y后进入Just值构造器。
接下來,看haskell的语法实现和do语法糖
add mx my =
mx >>= (\x ->
my >>= (\y ->
return (x + y)))
实现了上边写的add函数。用do语法糖就可以写成下边的形式.注意,do后语句在不加大括号和分号分割的情况下,缩进要一致。
add mx my = do
x <- mx
y <- my
return (x + y)