[Haskell-beginners] Maybe, Either
Conor McBride
conor at strictlypositive.org
Tue Sep 15 04:21:02 EDT 2009
Hi
This topic comes up a lot, and this is what I usually say when
it does. It's a thing I learned from James McKinna, many years
ago...
Might I gently suggest that there is a much better, more
natural way to abstract over every type-former which has
some sort of return/pure-like thing and some sort of mzero/empty
like thing? You could use the type-former which is inductively
defined to be the least such thing, and as such has a canonical
mapping to all the others, namely Maybe.
It's not necessarily a good idea to fix on Monad or MonadPlus
as there are other choices. For example,
On 15 Sep 2009, at 07:14, Yusaku Hashimoto wrote:
> I prefer Alternative to MonadPlus for explaining failure. It has
> better name and operator for failure and try-another.
>
> import Control.Applicative
>
> aLookup :: (Alternative f, Eq k) => k -> [(k,v)] -> f v
> aLookup key pairs = maybe empty pure $ lookup key pairs
there are notorious non-monadic instances for the above f
(some formulations of parsing, in particular). So,
>> I understand that fail being in Monad is controversial, but my
>> version of
>> the function works in *all* monads.
this is a touch presumptuous. On the one hand, Brent is right
when he says
> It doesn't work in *all* monads -- it only works in monads which
> support a sensible notion of failure.
but he's perhaps excessive when he says
> This is exactly what is captured by the MonadPlus constraint
> on my version of mLookup.
because it's not exact: it requires mplus as well as a sensible
notion of failure. And yes, why should we insist on (>>=) when
we just need a return and an mzero? Incidentally, I don't know
where the MonadPlus instance
> (IO, Maybe, [], ...) are already instances of MonadPlus.
of IO is coming from, but I want it caught and locked up now (in
STM, for example) before it does any permanent damage.
Why not factor out the failure-prone operations from the business
of interpreting failure in some failure-supporting context? Work
concretely while you can (types stay shorter, error messages make
more sense) then apply adapters
malt :: Alternative f => Maybe x -> f x
malt = maybe empty pure
mop :: MonadPlus m => Maybe x -> m x
mop = maybe mzero return
when you need to? This also reduces the risk of connecting an
ambiguous supplier to an ambiguous consumer, (show . read) style.
The message clearly bears repeating. Inductive definition is
a concrete form of abstraction. Don't be fooled by its
appearance: Maybe is the most abstract choice here -- the
classier options demand more structure than is needed and
thus exclude use-cases.
I'll crawl back under my stone now.
All the best
Conor
More information about the Beginners
mailing list