How to make a kinder, gentler "fail"?

This is probably a FAQ of sorts, but I found composing the proper search terms complicated. When I write simple parsers and the like I tend to prefer returning useful error strings instead of simply Nothing from Maybe. For example this is a common utility function of mine. Yes, I know with the addition of a Read n qualification I can make this more generic but it does not help with the current discussion. getNum :: String -> Either String Int getNum n = case reads n of [(x, "")] -> Right x [(x, cs)] -> Left $ "incomplete parse: " ++ cs cs -> Left $ "invalid number: " ++ cs But I would rather write the following so I am not bound to Either. This would even work with Maybe since Nothing just drops the string from fail. getNum :: Monad m => String -> m Int getNum n = case reads n of [(x, "")] -> return x [(x, cs)] -> fail $ "incomplete parse: " ++ cs cs -> fail $ "invalid number: " ++ cs Yeah, I know, no one likes the fact that fail raises an exception. What I would like to do in my code is define something like class (Monad a) => MonadGentle a where myreturn = return myfail s = fails s But I can not get an instance of this to compile because it insists myreturn and myfail are not visible. Since this comes up a lot in the tutorials and books, I am curious why there is not something like MonadGentle in Hackage or the libs. I use mzero occasionally, but as I said I usually prefer some information with my errors since it makes for more human usable results. Thanks.

Well, there's the 'failure' package. Another package builds on top of it, the control-monad-failure (easier to use, maybe). I read in the monad reader (don't remember the issue number) about it, and have used it ever since. The idea is to let the instanced monad decide what a failure means. Check it out, and comment back. Cheers. On Thu, 2011-05-26 at 11:15 -0700, Sean Perry wrote:
This is probably a FAQ of sorts, but I found composing the proper search terms complicated.
When I write simple parsers and the like I tend to prefer returning useful error strings instead of simply Nothing from Maybe.
For example this is a common utility function of mine. Yes, I know with the addition of a Read n qualification I can make this more generic but it does not help with the current discussion.
getNum :: String -> Either String Int getNum n = case reads n of [(x, "")] -> Right x [(x, cs)] -> Left $ "incomplete parse: " ++ cs cs -> Left $ "invalid number: " ++ cs
But I would rather write the following so I am not bound to Either. This would even work with Maybe since Nothing just drops the string from fail.
getNum :: Monad m => String -> m Int getNum n = case reads n of [(x, "")] -> return x [(x, cs)] -> fail $ "incomplete parse: " ++ cs cs -> fail $ "invalid number: " ++ cs
Yeah, I know, no one likes the fact that fail raises an exception. What I would like to do in my code is define something like
class (Monad a) => MonadGentle a where myreturn = return myfail s = fails s
But I can not get an instance of this to compile because it insists myreturn and myfail are not visible.
Since this comes up a lot in the tutorials and books, I am curious why there is not something like MonadGentle in Hackage or the libs. I use mzero occasionally, but as I said I usually prefer some information with my errors since it makes for more human usable results.
Thanks.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hi Sean,
The MonadError class in mtl might be what you're looking for:
http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Mona...
Here's what I came up with for your particular example, along with tests in
both the (Either String) monad and the IO monad:
http://hpaste.org/47101/monaderror_example
Note that if you want to use Maybe, you'll have to make a custom instance of
MonadError for Maybe, since it doesn't exist by default.
Cheers,
Adam
On Thu, May 26, 2011 at 2:15 PM, Sean Perry
This is probably a FAQ of sorts, but I found composing the proper search terms complicated.
When I write simple parsers and the like I tend to prefer returning useful error strings instead of simply Nothing from Maybe.
For example this is a common utility function of mine. Yes, I know with the addition of a Read n qualification I can make this more generic but it does not help with the current discussion.
getNum :: String -> Either String Int getNum n = case reads n of [(x, "")] -> Right x [(x, cs)] -> Left $ "incomplete parse: " ++ cs cs -> Left $ "invalid number: " ++ cs
But I would rather write the following so I am not bound to Either. This would even work with Maybe since Nothing just drops the string from fail.
getNum :: Monad m => String -> m Int getNum n = case reads n of [(x, "")] -> return x [(x, cs)] -> fail $ "incomplete parse: " ++ cs cs -> fail $ "invalid number: " ++ cs
Yeah, I know, no one likes the fact that fail raises an exception. What I would like to do in my code is define something like
class (Monad a) => MonadGentle a where myreturn = return myfail s = fails s
But I can not get an instance of this to compile because it insists myreturn and myfail are not visible.
Since this comes up a lot in the tutorials and books, I am curious why there is not something like MonadGentle in Hackage or the libs. I use mzero occasionally, but as I said I usually prefer some information with my errors since it makes for more human usable results.
Thanks.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
On Thu, May 26, 2011 at 2:24 PM, Elvio Toccalino
Well, there's the 'failure' package. Another package builds on top of it, the control-monad-failure (easier to use, maybe). I read in the monad reader (don't remember the issue number) about it, and have used it ever since. The idea is to let the instanced monad decide what a failure means. Check it out, and comment back.
Cheers.
This is probably a FAQ of sorts, but I found composing the proper search terms complicated.
When I write simple parsers and the like I tend to prefer returning useful error strings instead of simply Nothing from Maybe.
For example this is a common utility function of mine. Yes, I know with
addition of a Read n qualification I can make this more generic but it does not help with the current discussion.
getNum :: String -> Either String Int getNum n = case reads n of [(x, "")] -> Right x [(x, cs)] -> Left $ "incomplete parse: " ++ cs cs -> Left $ "invalid number: " ++ cs
But I would rather write the following so I am not bound to Either. This would even work with Maybe since Nothing just drops the string from fail.
getNum :: Monad m => String -> m Int getNum n = case reads n of [(x, "")] -> return x [(x, cs)] -> fail $ "incomplete parse: " ++ cs cs -> fail $ "invalid number: " ++ cs
Yeah, I know, no one likes the fact that fail raises an exception. What I would like to do in my code is define something like
class (Monad a) => MonadGentle a where myreturn = return myfail s = fails s
But I can not get an instance of this to compile because it insists myreturn and myfail are not visible.
Since this comes up a lot in the tutorials and books, I am curious why
On Thu, 2011-05-26 at 11:15 -0700, Sean Perry wrote: the there is
not something like MonadGentle in Hackage or the libs. I use mzero occasionally, but as I said I usually prefer some information with my errors since it makes for more human usable results.
Thanks.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
Adam Foltzer
-
Elvio Toccalino
-
Sean Perry