#2309: containers: specialize functions that fail in a Monad to
Maybe
Dan Doel
dan.doel at gmail.com
Sun May 25 07:58:44 EDT 2008
On Sunday 25 May 2008, Yitzchak Gale wrote:
> I personally would be happy with either Maybe or MonadPlus.
>
> I hope we don't miss out on getting rid of fail by arguing
> about Maybe vs. MonadPlus.
I don't think we should get rid of fail. There's nothing wrong with it, per
se. It just shouldn't be in Monad, it should be in MonadPlus (or MonadZero if
things get split back up 1.4 style). fail is mzero that takes a string to
explain what happened. In fact, if the functions were revised to be
restricted to MonadPlus, I'd expect it'd be a change only in the declared
type signature. They'd likely still call fail because it provides slightly
more information to the monads that can actually use it (Either e, IO, ...).
Having both fail and mzero as failure options isn't a real problem, because
they should do the same thing in monads that have both (at least, off the top
of my head; I may be forgetting some). The problem is calling fail in monads
that don't have an mzero, because they don't have a notion of failure.
> Maybe is not arbitrary. It is the "unit" instance of MonadPlus. It can be
> lifted trivially into any other instance.
I didn't mean to say that Maybe is arbitrary. I meant that specializing to
Maybe makes it more inconvenient to use with other MonadPlus instances, and I
don't see a benefit to counter that.
Yes, you can trivially inject Maybe into an arbitrary MonadPlus. You can do it
for any Foldable, in fact:
Data.Foldable.msum . fmap return
But having to write liftMaybe whenever you want that has the potential to be
annoying. We currently have the same problem with IO functions, where you
have to stick a liftIO on everything if you want to wrap IO in a monad
transformer.
That's not to mention potential information loss compared to fail. For
instance, readMaybe doesn't subsume readIO, because the latter can report the
difference between no parse and ambiguous parses. Using Either String covers
that, except it's not declared a Monad except in mtl, because fail is in the
wrong place.
I just think it's frustrating that we have abstractions that do exactly what
we want, and then don't use them. :)
-- Dan
More information about the Libraries
mailing list