[Haskell-beginners] How to make a kinder, gentler "fail"?

Sean Perry shaleh at speakeasy.net
Thu May 26 20:15:36 CEST 2011


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.




More information about the Beginners mailing list