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
Monad(单子)是个类型类,它至少包含一个return函数以及一个bind(>>=)操作符。
Monad的法则
Left identity: return a >>= f ≡ f a
Right identity: m >>= return ≡ m
Associativity: (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
[] 是 Monad
instance Monad [] where
return x = [x]
xs >>= f = [y | x <- xs, y <- f x]
xs >> ys = [y | _ <- xs, y <- ys]
fail _ = []
Prelude> [3,4,5] >>= \x -> [x,-x]
[3,-3,4,-4,5,-5]
Prelude> do { x <- [3,4,5]; [x,-x] }
[3,-3,4,-4,5,-5]
证明[]符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f ≡ [a] >>= f ≡ [y | x <- [a], y <- f x] ≡ [y | y <- f a] ≡ f a
2. m >>= return ≡ m
m >>= return ≡ [y | x <- m, y <- return x] ≡ [y | x <- m, y <- [x]] ≡ [x | x <- m] ≡ m
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(m >>= f) >>= g
≡ [y | x <- m, y <- f x] >>= g
≡ [y | x <- [y | x <- m, y <- f x], y <- g x]
≡ [z | x <- m, y <- f x, z <- g y]
m >>= (\x -> f x >>= g)
≡ m >>= (\x -> [z | y <- f x, z <- g y])
≡ [y | x <- m, y <- (\x -> [z | y <- f x, z <- g y]) x]
≡ [y | x <- m, y <- [z | y <- f x, z <- g y]]
≡ [z | x <- m, y <- f x, z <- g y]
Maybe 是 Monad
instance Monad Maybe where
return = Just
(Just x) >>= k = k x
Nothing >>= _ = Nothing
Just _m1 >> m2 = m2
Nothing >> _m2 = Nothing
fail _ = Nothing
Prelude> Just 9 >>= \x -> return (x*10)
Just 90
Prelude> do { x <- Just 9; return (x*10) }
Just 90
Prelude> Nothing >>= \x -> return (x*10)
Nothing
证明Maybe符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f ≡ Just a >>= f ≡ f a
2. m >>= return ≡ m
Just x >>= return ≡ return x ≡ Just x
Nothing >>= return ≡ Nothing
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(Just x >>= f) >>= g ≡ f x >>= g
(Nothing >>= f) >>= g ≡ Nothing >>= g ≡ Nothing
Just x >>= (\x -> f x >>= g) ≡ (\x -> f x >>= g) x ≡ f x >>= g
Nothing >>= (\x -> f x >>= g) ≡ Nothing
Either a 是 Monad
data Either a b = Left a | Right b
instance Monad (Either e) where
return = Right
Left l >>= _ = Left l
Right r >>= k = k r
Prelude> Left "boom" >>= \x -> return (x+1)
Left "boom"
Prelude> Right 3 >>= \x -> return (x + 100) :: Either String Int
Right 103
证明Either a符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f ≡ Right a >>= f ≡ f a
2. m >>= return ≡ m
Right r >>= return ≡ return r ≡ Right r
Left l >>= return ≡ Left l
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(Right r >>= f) >>= g ≡ f r >>= g
(Left l >>= f) >>= g ≡ Left l >>= g ≡ Left l
Right r >>= (\x -> f x >>= g) ≡ (\x -> f x >>= g) r ≡ f r >>= g
Left l >>= (\x -> f x >>= g) ≡ Left l
((->) r) 是 Monad
instance Monad ((->) r) where
return = const
x >>= f = \r -> f (x r) r
Prelude> (*2) >>= (\a -> (+10) >>= (\b -> return (a+b))) $ 3
19
Prelude> do { a <- (*2); b <- (+10); return (a+b) } $ 3
19
do { a <- (*2); b <- (+10); return (a+b) } $ 3 = (3*2)+(3+10) = 19
证明((->) r)符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f ≡ const a >>= f ≡ \r -> f (const a r) r ≡ \r -> f a r ≡ f a
2. m >>= return ≡ m
m >>= return ≡ \r -> return (m r) r ≡ \r -> const (m r) r ≡ \r -> m r ≡ m
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(m >>= f) >>= g
≡ (\x -> f (m x) x) >>= g
≡ \r -> g ((\x -> f (m x) x) r) r
≡ \r -> g (f (m r) r) r
m >>= (\x -> f x >>= g)
≡ \r -> (\x -> \y -> g (f x y) y) (m r) r
≡ \r -> g (f (m r) r) r
fish operator 鱼形操作符
(>=>) 与 (<=<)
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
f >=> g = (\x -> f x >>= g)
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)
两种Monad的结合运算
Monad的法则(2)
Left identity: f <=< return ≡ f
Right identity: return <=< f ≡ f
Associativity: f <=< (g <=< h) ≡ (f <=< g) <=< h
Left identity: return >=> f ≡ f
Right identity: f >=> return ≡ f
Associativity: f >=> (g >=> h) ≡ (f >=> g) >=> h
证明两种Monad法则等价:
1. return a >>= f ≡ f a 等价于 f <=< return ≡ f
f <=< return ≡ f
=> (\x -> return x >>= f) ≡ f
=> (\x -> return x >>= f) a ≡ f a
=> return a >>= f ≡ f a
2. m >>= return ≡ m 等价于 return <=< f ≡ f
return <=< f ≡ f
=> (\x -> f x >>= return) ≡ f
=> (\x -> f x >>= return) a ≡ f a
=> f a >>= return ≡ f a
=> m >>= return ≡ m
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g) 等价于 f <=< (g <=< h) ≡ (f <=< g) <=< h
f <=< (g <=< h) ≡ (f <=< g) <=< h
=> f <=< (\x -> h x >>= g) ≡ (\x -> g x >>= f) <=< h
=> (\y -> (\x -> h x >>= g) y >>= f) ≡ (\y -> h y >>= (\x -> g x >>= f))
=> (\y -> h y >>= g >>= f) ≡ (\y -> h y >>= (\x -> g x >>= f))
=> (\y -> h y >>= g >>= f) a ≡ (\y -> h y >>= (\x -> g x >>= f)) a
=> h a >>= g >>= f ≡ h a >>= (\x -> g x >>= f)
=> m >>= g >>= f ≡ m >>= (\x -> g x >>= f)
=> m >>= f >>= g ≡ m >>= (\x -> f x >>= g)
反向 bind 操作符 (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b
f =<< x = x >>= f
Prelude Control.Monad> print =<< return 1
1