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

Adam Foltzer acfoltzer at gmail.com
Thu May 26 22:43:32 CEST 2011


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-Monad-Error-Class.html#t:MonadError

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 <shaleh at speakeasy.net> 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>


On Thu, May 26, 2011 at 2:24 PM, Elvio Toccalino
<elviotoccalino at gmail.com>wrote:

> 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 at haskell.org
> > http://www.haskell.org/mailman/listinfo/beginners
>
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110526/c7ce62d1/attachment.htm>


More information about the Beginners mailing list