State monads don't respect the monad laws in Haskell

George Russell ger@tzi.de
Tue, 14 May 2002 16:57:12 +0200


Simon Marlow wrote
[snip]
> So the IO monad in Haskell, at least as we understand it, doesn't
> satisfy the monad laws (or, depending on your point of view, seq breaks
> the monad laws).
[snip]

Cheers Simon.  One of the awkward things about the Haskell events I implemented
is that although I make them an instance of Monad, they don't actually satisfy
left identity.  Now I can say that "Yes, Event isn't really a Monad, but neither is IO".

According to the report
> Instances of Monad should satisfy the following laws:                        
>                                                                                 
>    return a >>= k          = k a                                                
>    m >>= return            = m                                                  
>    m >>= (\x -> k x >>= h) = (m >>= k) >>= h  
so neither IO nor my events satisfy this.  Up to now I haven't had any problems
with this.

Does GHC or any other Haskell compiler actually rely on instances of Monad
satisfying left identity?  If not, I would suggest dropping the requirement, if it
can be done without upsetting category theorists.  (What the hell, they stole the
term "Monad" from philosophy and changed its meaning, so why shouldn't we?)

I presume it would not in fact be difficult to synthesise a left identity at
the cost of making things slower, thus (forgive any syntax errors, I'm not going to
test this).

data MonadIO a = Action (IO a) | Return a
instance Monad (MonadIO a) where
   return a = Return a
   (>>=) (Return a) k = k a
   (>>=) (Action act) f = 
      Action (act >>= (\ a -> case f a of {Return a -> return a;Action act -> act}))

(I considered doing something similar to turn Events into a real monad, but decided to
choose efficiency over category theory.  For events its slightly more complicated as
you need to handle the choice operator as well.)