State monads don't respect the monad laws in Haskell

S.M.Kahrs S.M.Kahrs@ukc.ac.uk
Tue, 14 May 2002 16:48:31 +0100


George Russel wrote:
[snip]
> I presume it would not in fact be difficult to synthesise a left identi=
ty at
> the cost of making things slower, thus (forgive any syntax errors, I'm =
not going to
> test this).
> =

> data MonadIO a =3D Action (IO a) | Return a
> instance Monad (MonadIO a) where
>    return a =3D Return a
>    (>>=3D) (Return a) k =3D k a
>    (>>=3D) (Action act) f =3D =

>       Action (act >>=3D (\ a -> case f a of {Return a -> return a;Actio=
n act -> act}))

Or, more general:

data MonadWrap m a =3D M (m a) | R a
instance Monad m =3D> Monad (MonadWrap m) where
    return =3D R
    R x >>=3D f =3D f x
    M x >>=3D f =3D M (x >>=3D \a->case f a of
                                R b -> return b
                                M c -> c)

I don't think this really solves the problem with the left unit
(not in general, and not for IO either),
it merely pushes it to a different place.
I think you need the left-unit law for monad m
to prove the 'associativity' law for monad (MonadWrap m)
The 'associativity' law:
	 m >>=3D (\x -> k x >>=3D h) =3D (m >>=3D k) >>=3D h
The case in which the situation occurs is m=3D(M x) with (k x)=3D(R b).

Stefan Kahrs