[Haskell-cafe] How to combine Error and IO monads?

Cat Dancer haskell-cafe at catdancer.ws
Thu Dec 7 12:02:30 EST 2006

I've read Jeff Newbern's tutorial on monad transformers
(http://www.nomaware.com/monads/html/index.html), but I don't grok it
yet and I can't tell how to get started with this particular
requirement, or even if I need monad transformers for this.

I have a program that performs a series of IO operations, each which
can result in an error or a value.  If a step returns a value I
usually want to pass that value on to the next step, if I get an error
I want to do some error handling but usually want to skip the
remaining steps.

Thus I have a lot of functions with return types like IO (Either
String x), where x might be (), Integer, or some other useful value
type, and a lot of case statements like

  a :: Integer -> IO (Either String String)
    (a :: Either String Integer) <- some_io_action_returning_integer_or_error
    case a of
      -- got to get from (Either String Integer) to (Either String String)
      Left message -> return $ Left message
      -- continue on
      Right i -> do_more i

If I was using just Either I know how to get rid of the case statements:

  import Control.Monad.Error

  p :: Integer -> Either String Integer
  q :: Integer -> Either String String

  r :: Either String String
  r = do
    a <- p 3
    b <- q a
    return b

which of course is much nicer.  But how do I combine the Error and IO
monads so that r could have the type IO (Either String String)?

More information about the Haskell-Cafe mailing list