# MonadCont, MonadFix

**Magnus Carlsson
**
magnus@cse.ogi.edu

*Sat, 9 Mar 2002 11:38:00 -0800*

Ashley Yakeley writes:
> Are there any useful monads that are instances of both MonadCont and=
=20
> MonadFix? I can't make the two meet. Perhaps this is because=20
> continuations have no fixed point, or something. Very annoying.
If you have a recursive monad with first-class references (such as IO
or ST s), you can define a continuation monad on top of it with an
instance of MonadFix I enclose below. The instance seems to make
sense operationally, but as Levent Erk=F6k has pointed out, it doesn't
satisfy the left-shrinking axiom for recursive monads:
fixM (\x -> a >>=3D f x) =3D=3D a >>=3D \y -> fixM (\x -> f x=
y)
This axiom comes from Levent's and John Launchbury's ICFP'00
paper, see
http://www.cse.ogi.edu/PacSoft/projects/rmb/
Moreover, I suspect that the instance breaks the axiom for callcc,
which shows how any evaluation context E can be pushed inside a
callcc:
E[callcc e] =3D callcc (\k' -> E[e (\z -> k' (E[z]))]
This is for callcc without monadic types, see Sabry's and Friedman's
paper on "Recursion is a Computational Effect", at
http://www.cs.indiana.edu/hyplan/sabry/papers/
/M
--
class Monad m =3D> FixMonad m where
fixM :: (a -> m a) -> m a
class Monad m =3D> Ref m r | m -> r where
newRef :: a -> m (r a)
readRef :: r a -> m a
writeRef :: r a -> a -> m ()
newtype C m a =3D C ((a -> m ()) -> m ())
deC (C m) =3D m
instance (FixMonad m, Ref m r) =3D> FixMonad (C m) where
fixM m =3D C $ \k -> do
x <- newRef Nothing
a <- fixM $ \a -> do
deC (m a) $ \a -> do
ma <- readRef x
case ma of=20
Nothing -> do writeRef x (Just a)
Just _ -> k a
ma <- readRef x
case ma of
Just a -> return a
Nothing -> error "fixM"
k a