[Haskell-beginners] combining two monads

Daniel Schoepe daniel.schoepe at googlemail.com
Tue Aug 23 02:48:41 CEST 2011


On Mon, 22 Aug 2011 19:51:18 +0300, Ovidiu Deac <ovidiudeac at gmail.com> wrote:
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110823/b3b2874e/attachment.pgp>


More information about the Beginners mailing list