A really great little paper on Monads is called "Monads for functional programming" by Philip Wadler, and it can be found off his home page at http://homepages.inf.ed.ac.uk/wadler/topics/monads.html. I decided to translate one of his samples into Hugs98 using the Prelude's Monad class (Philip invents his own dialectic for monads, perfectly fine, but doesn't leverage the "do" sugar nor the other convenience operators in the Prelude). Rather than drone on about the meaning of it, I'll just paste for your enjoyment and watch the feedback section for questions. This is example 2.8 from the paper, in modern lingo. Obviously, I'm going somewhere with all this, and time will tell.
file eval5_a.lhs:
Variation two, State, revised, Library version
In a state monad, a computation accepts a state and returns a (state,
value) pair.
> type St = Int
> data M a = M (St -> (St, a))
> data Term = Con Int
> | Div Term Term
> | Add Term Term
> deriving Show
> instance Monad M where
> return v = M (\st -> (st, v))
> M fst0 >>= famb =
> M $ \st0 ->
> let (st1, v1) = fst0 st0
> M fst1 = famb v1
> in fst1 st1
> tick :: M ()
> tick = M (\st -> (st+1, ()))
> eval :: Term -> M Int
> eval (Con a) = return a
> eval (Div t u) =
> do r1 <- eval t
> r2 <- eval u
> tick >> return (r1 `div` r2)
> answer, error' :: Term
> answer = (Div (Div (Con 1972 ) (Con 2 )) (Con 23 ))
> error' = (Div (Con 1 ) (Con 0 ))
> main =
> let M e1 = (eval answer)
> M e2 = (eval error')
> in (e1 0, e2 0)