monad 是支持>>=
操作的 applicative 函子,>>=
讀作綁定虏劲,它的類型是:
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
即取一個(gè) monad 和一個(gè)函數(shù)赊抖,返回一個(gè)新的 monad。monad 有專屬的類型類——Monad肤晓,其定義如下:
class Applicative m => Monad (m :: * -> *) where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
return
和 applicative 的pure
一樣,都是取一個(gè)值认然,把它放在能產(chǎn)生這個(gè)值的最小默認(rèn)上下文中补憾。>>=
前面說(shuō)過(guò)了,>>
有一個(gè)默認(rèn)實(shí)現(xiàn)卷员,就是把一個(gè) monad 直接換成另一個(gè) monad 返回盈匾,fail
不會(huì)被主動(dòng)調(diào)用,在一些特定語(yǔ)法結(jié)構(gòu)中毕骡,會(huì)被 Haskell 用于模式匹配削饵。
一個(gè)類型要成為 monad 不僅要滿足 Monad 類型類的條件,還要滿足 monad 定律(雖然編譯器并不會(huì)幫你檢查):
- 左單位元:return x >>= f 和 f x 等價(jià)
- 右單位元:m >>= return 和 m 等價(jià)
- 結(jié)合律:(m >>= f) >>= g 和 m >>= (\x -> f x >>= g) 等價(jià)