[Haskell-cafe] Using MonadError within other Monads

Andrew Pimlott andrew at pimlott.net
Mon Dec 19 01:37:11 EST 2005

[It is best to post questions only to haskell-cafe.]

On Mon, Dec 19, 2005 at 03:53:53PM +1300, Karl Grapone wrote:
> I'm having trouble making use of MonadError within another Monad, in
> this case IO.
> I've blundered around for a while, trying various combinations of
> things, but I don't think I've fully cottoned-on to nesting of monads.

Looking at the signature of f,

> f :: IO (Either String String)

"Either String String" is just an ordinary value produced in the IO
monad--the monad structure of IO and "Either String" are completely
independent.  With that in mind, here is a way to make part of your code

    g n = do
        c <- getChar
        cs <- g (n-1)
        return $ do c' <- mapErrs (h c)
                    cs' <- cs
                    return (c':cs')

The outer do is a computation in the IO monad, the inner do is a
computation in the "Either String" monad, and the net effect is an IO
computation returning an "Either String" computation--which is just what
the type signature says.  I had to change your code in 3 other places to
make it type-check; hopefully you can now find them. ;-)

When people speak of nesting monads, they often mean using monad
transformers.  If you were using the ErrorT monad transformers, your
signature would look like

    f :: ErrorT String IO String

You might want to try rewriting your code that way, but I would suggest
making it work with the current type signatures first.


More information about the Haskell-Cafe mailing list