Theory
- A monad is a type constructor
mplus two combinators that let you run one computation after another while hiding the low-level plumbing. - Laws:
return :: a -> m aโโ inject a pure value.(>>=) :: m a -> (a -> m b) -> m bโโ pass the result of step 1 into step 2 (a.k.a. bind).
- Consequence:
- Error handling:
Either e astops on the firstLeft. - State threading:
State s apasses new state forward. - Non-determinism:
[a]explores every possibility. - Input/Output:
IO atalks to the outside world safely.
- Error handling:
- Do-notationโ
do { x โ m1; y โ m2; โฆ }is just pretty syntax for nested>>=chains, making monadic code read top-to-bottom.
Implementation
-- Generic interface
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m aExample: Error Monad (Either)
type Result a = Either String a -- alias
instance Monad Result where
Left err >>= _ = Left err -- abort on first error
Right v >>= f = f v -- continue on success
return = RightUsing it with do:
eval (Plus e1 e2) = do
v1 <- eval e1 -- Result Int
v2 <- eval e2
return (v1 + v2)The (>>=) instance removed every explicit case on Either.
Swapping effects
Just switch a type aliasโthe function bodies stay identical:
type Interpreter a = State Int a -- counts operations
-- or
type Interpreter a = [a] -- explores branchesDifferent monads choose how steps are sequenced without touching the high-level logic.