[Haskell-cafe] Monad Transformer question

Andrew Pimlott andrew at pimlott.net
Tue Nov 22 19:58:00 EST 2005

On Tue, Nov 22, 2005 at 05:26:00PM -0700, Fan Wu wrote:
>    type NDS a = StateT ProblemState [] a
>    getVar :: Var -> NDS (Maybe Value)
>    getVar v = do vs <- gets vars
>                  return $ lookup v vs
> What puzzles me is that, I think the Monad of the do block shall be
> the "NDS (Maybe Value)" in declaration, but the type of gets is
>     gets :: (MonadState s m) => (s -> a) -> m a
> So "gets" returns a Monad of type m ([] is this case), which seems to
> be different from "NDS (Maybe Value)", but GHC does not complain about
> it.
> If I comment out the type declaration of "getVar :: Var -> NDS (Maybe
> Value)" and let GHC interpret the type, then the type of getVar is
> like:
>     getVar :: (MonadState ProblemState m) => Var -> m (Maybe Value)
> So does it mean "StateT ProblemState m" and the "m" as in "MonadState
> ProblemState m" is the same thing?

No!  Check out the instance:

    instance (Monad m) => MonadState s (StateT s m) where ...

So you can see that the "m" in "MonadState ProblemState m" is actually
"StateT ProblemState m'" where m' is the inner monad, [] in your case.
So a correct type for gets as you use it is

    gets :: (ProblemState -> a) -> MonadState ProblemState [] a


More information about the Haskell-Cafe mailing list