FunDeps & Monad transformers

Jose Emilio Labra Gayo labra@lsi.uniovi.es
Mon, 26 Feb 2001 12:40:32 +0100


I was using monad transformers with definitions like the following:

> -- class Monad m => StateMonad s m
> --  where update :: (s -> s) -> m s

However, if I try to define

> test :: ( StateMonad s m, Num s ) => m ()
> test = do { update (+1) ; return () }

I obtain

ERROR ... - Ambiguous type signature in type declaration
*** ambiguous type : (StateMonad a b, Num a) => b ()
*** assigned to    : test

I thought that functional dependencies could be useful
to solve those typings. So I wrote:

> class Monad m => StateMonad s m | m -> s
>  where update :: (s -> s) -> m s

And now, the 'test' function loads with Hugs.

However, when I try to declare the following instances (which previously
worked ok):

> class (Monad m, Monad (t m)) => MonadT t m where
>  lift :: m a -> t m a

> newtype StateT s m v = S (s -> m (v,s))

> instance ( StateMonad s m
>          , MonadT t m) => StateMonad s (t m)
>  where update = lift . update

> instance Monad m => StateMonad s (StateT s m)
>   where update f = S (\s -> return (s, f s))

I obtain the following error

ERROR ... - Instances are not consistent with dependencies
*** This instance    : StateMonad a (StateT a b)
*** Conflicts with   : StateMonad a (b c)
*** For class        : StateMonad a b
*** Under dependency : b -> a

Is it possible to define those declarations?

Best regards, Jose Labra
http://lsi.uniovi.es/~labra