[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