[Haskell-cafe] Re: what is inverse of mzero and return?
Jorge Adriano Aires
jadrian at mat.uc.pt
Sun Jan 23 00:10:28 EST 2005
> >concat (map c (a ++ b)) = concat (map c a) ++ concat (Map c b),
> >
> >which is easily seen to be true (if applying c to an element of a causes
> > an error, neither side will go past that).
> >
> >Daniel
>
> So do we consider [] to be fail?, Monad.hs defines:
I will ignore "fail" if you don't mind. I can only think of it as a convenient
hack. I'll get to failure later. If the monad represents a state then IMO
mplus should be the most intuitive definition for the sum of two such states.
> instance MonadPlus [] where
> mzero = []
> mplus = (++)
On the list monad, I think of the mplus operation as the "union" two
non-deterministic states. Mzero is the state that works as the identity
(which is when you have no possible state at all).
MonadPlus instances for Parsers are similar, p1 mplus p2 is a parser p that
will return the concatenation of the [(a, string)] lists that would be
returned by p1 and p2.
The datatype Maybe, on the other hand, just allows us to keep at most one
valid state. Summing "no state" with "some state" gives "some state", if we
have two states, we get to keep the first.
And all seems fine to me, and I haven't mentioned failure.
> What would happen if this was the definition?
>
> instance MonadPlus [] where
> mzero = []
> mplus a b
>
> | a == [] = b
> | otherwise = a
Then, I'd say you're not thinking of monadic sums, but of catching errors, and
the appropriate place for that is the class MonadError.
Such a function can easily be written in terms of catchError. It seems quite
useful, so it would probably make a good method with default instance:
skipError x y = catchError x (\_->y)
And of course we need MonadError instances for Maybe and Lists.
instance MonadError () Maybe where
throwError _ = Nothing
Nothing `catchError` h = h ()
jx `catchError` _ = jx
instance MonadError () [] where
throwError _ = []
[] `catchError` h = h ()
xs `catchError` _ = xs
The Maybe datatype is used to model computation errors all the time, so I
never understood why its MonadError instance was not provided. The List
instance seems pretty fair too.
And there you have,
skipError [1,2] [] = [1,2]
skipError [] [1,2] = [1,2]
skipError [1,2] [3,4] = [1,2]
J.A.
More information about the Haskell-Cafe
mailing list