[Haskell-cafe] Re: nested maybes

Yitzchak Gale gale at sefer.org
Mon Feb 5 07:32:07 EST 2007


J. Garrett Morris wrote:
> This is where my favorite part of the mtl steps in: monad transformers.

I agree, the Error monad is very helpful here.

> First, we'll create a transformed version of the IO monad,

Why go to the trouble of creating a new monad?
The existing ones are fine.

(While writing this, I just saw Bulat's posts. Nice!)

It would be nicest if we had MaybeT available, as in
http://www.haskell.org/haskellwiki/New_monads/MaybeT

Then you could just write:

import Control.Monad.Maybe

main = runMaybeT $ doIt `mplus` liftIO printError
 where
   doIt = do
     input <- MaybeT getInput
     result <- MaybeT $ processInput input
     liftIO $ printResult result

You could simplify things if you
change the types from IO (Maybe a) to
MaybeT IO a. Then you would have:

main = runMaybeT $ doIt `mplus` liftIO printError
 where
   doIt = do
     input <- getInput
     result <- processInput input
     liftIO $ printResult result

But you might want to do something more
robust with the error reporting. Then you
would do this:

import Control.Monad.Error

data MyError = InputError | OutputError | Unknown String
instance Error MyError where
  noMsg = Unknown "Oops"
  strMsg x = Unknown x

Then make the type of printError
printError :: MyError -> IO ()

and we have:

main = runErrorT $ doIt `catchError` (liftIO . printError)
 where
   doIt = do
     input <- liftIO getInput >>= maybe (throwError InputError) return
     result <- liftIO (processInput input) >>= maybe (throwError
OutputError return
     liftIO $ printResult result

Again, you can simplify things if you do
change the types, using ErrorT MyError IO a
in place of IO (Maybe a), etc., and put the
throwError calls inside the functions.

main = runErrorT $ doIt `catchError` (liftIO . printError)
 where
   doIt = do
     input <- getInput
     result <- processInput input
     liftIO $ printResult result

Regards,
Yitz


More information about the Haskell-Cafe mailing list