
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)?