Monads
- s.6.3.6, p.90, RR, Class Monad:
class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a m >> k = m >>= \ _ -> k fail s = error s
Think of m a as being the (type of) a "step" in a sequence of operations, and of >> as being an operator, like `;' in an imperative language, which connects a sequence of steps together. >>= is like >> except that the former's right operand takes a parameter of type a.
Note that >> is defined in terms of >>= for brevity and consistency; they behave in essentially the same way. Below we see that >>= must be (essentially) associative and that therefore >> must be associative, i.e. p>>(q>>r) = (p>>q)>>r.
- ". . . Instance of Monad should [obey]":
return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k)>>= h --~associative± fmap f xs = xs >>= return . f
"... lists, Maybe and IO are all instances of Monad. .... for IO, the fail method invokes error."
>>= | >> | return | fail | |
---|---|---|---|---|
Monad defn | (>>=) :: m a -> (a->m b) -> mb | (>>) :: m a -> m b -> m b | return :: a -> m a | fail :: String -> m a |
m >> k = m >>= \_ -> k --default | fail s = error s --default | |||
instances... | ||||
IO | (>>=) =... --~magic | --"-- | return =... --~magic | fail s = error s |
[] list | m >>= k = concat(map k m) | --"-- | return x = [x] | fail s = [] |
Maybe |
(Just x) >>= k = k x Nothing >>= k = Nothing | --"-- | return = Just --~success | fail s = Nothing |
Example: [m.hs] |
---|
module Main where main = putStrLn "-- Monad experiments, 11/2005 --" -- example 1.1 m = list >> (putStrLn.show) -- equiv to... ( ["anna", "carol"] >>= \x -> -- do x <- [..., ...] ["bill", "dave" ] >>= \y -> -- y <- [..., ...] return (x,y) -- return (x,y) ) --[(a,b), (a,d), (c,b), (c,d)] -- example 1.2 m = list >> (putStrLn.show) ( ["anna", "carol"] >>= \x -> concat [ return [x], -- blob with TV ["bill", "dave" ] >>= \y -> -- a date? if x > y then fail "bad vibe" else return [x,y] ] ) --[[a],[a,b],[a,d],[c],[c,d]] -- example 2 m = Maybe >> let sqrt x = if x >= 0 then Just(x**0.5) else Nothing in (putStrLn.show) ( sqrt 4 >>= \x -> sqrt 9 >>= \y -> return (x+y) ) -- Just 5.0 -- example 3 m = IO >> return "print-me" >>= putStrLn >> fail "-- stopping by invoking IO's fail --" -- ------------------------------------------------LA--11/2005-- |
RR = revised report, CUP, 2003.
7/2002, 11/2005