
On Mon, 22 Aug 2011 19:51:18 +0300, Ovidiu Deac
Hi,
I wrote some code and I want to refactor it to use the Error monad combined with IO operations. I found some examples of monad transformers but I didn't really get them.
So I have a function in IO monad which does several operations which might fail. These operations work with files so they have to be in IO monad but on the other hand I would like to use Error monad such that I can throw errors.
For this you need to use a monad transformer instead, in this case ErrorT. Monad transformers are given an "inner monad", in this case IO, and usually the same parameters the "original" monad, in this case Either, expected. A monad transformer normally comes with a runFooT function that returns a value in the inner monad. RWH has a chapter on monad transformers that explains them more clearly: http://book.realworldhaskell.org/read/monad-transformers.html Here's a shortened version of your example: import Control.Monad.Error data Config = Config deriving Show data MyError = ConfigError | ParseEerror | OtherError String deriving Show instance Error MyError where strMsg = OtherError loadConfig :: String -> ErrorT MyError IO Config loadConfig _ = do lift $ putStrLn "foo" -- `lift' is necessary to turn an IO action into an ErrorT action throwError ConfigError main = print =<< runErrorT (loadConfig "foo") The result type in your code, "Either MyError (IO Config)", would mean that the function decides, without doing any IO, whether or not to return an error and, if not, return an IO action that will read the config. Cheers, Daniel