[Haskell-cafe] Re: nested maybes
gale at sefer.org
Tue Feb 6 11:00:34 EST 2007
J. Garrett Morris wrote:
> Again, from the earlier example, I'm not sure how typing:
> apply :: (MonadCont m, MonadState Blargh m, MonadError Fzzt m, MonadIO m) =>
> Handle -> Attribute a -> m a
> is simpler than
> apply :: Handle -> Attribute a -> m a
Well, no, but it is at least no worse than
apply :: Handle -> Attribute a ->
ContT (StateT Blargh (ErrorT Fzzt IO)) a
I find that in general, many functions do
not need all of the capabilities. If they do,
you can alias that also:
class (MonadCont m, MonadState Blargh m, MonadError Fzzt m, MonadIO m) =>
instance MyContext (ContT (StateT Blargh (ErrorT Fzzt IO)))
apply :: MyContext m => Handle -> Attribute a -> m a
> > 2. Use a type alias for the monad stack.
> At least as of 6.4.2, GHC printed the expanded types, not the aliases,
> in error messages.
Hmm, I'm not sure. I use a more recent GHC.
I know I have seen type aliases in error messages,
but I am not certain that they are always used.
>> (There are other big advantages of both of these.)
> Those being?
OK, let's see...
You often need to make changes to the monad stack -
add or remove capabilities, reorder, etc. This way,
you only change the type in one place, and only
fix functions that use the particular capabilities that
The usual advantages of polymorphism apply -
gives separation of concerns, encourages reuse,
eases maintenance and testing, better expresses
the meaning of the function by not mentioning
Monad transformers are like Lego blocks. I find
that almost always, different parts of a system
need to use different combinations of common
monad stack fragments, assembled in different
ways. Polymorphism makes that a lot easier to do,
and results in functions that are much more
By the way, are you really doing CPS? If you are
only using ContT to get short-circuiting, you could
probably also simplify things by using ExitT
More information about the Haskell-Cafe