
So, anyone? What are the laws that MonadPlus is supposed to satisfy? The obvious ones are that if MonadPlus m then for all types a, (m a) should be a monoid. But, what about the others, because IO does not appear to satisfy a >> mzero == mzero Jules

I believe that these are the relevant laws of class MonadPlus: m >>= (\x -> mzero) = mzero mzero >>= m = mzero m `mplus` mzero = m mzero `mplus` m = m You can get some intuition for this by thinking of mplus as +, mzero as 0, and >>= as multiplication. I haven't follow much at all of this thread, but, for what it's worth, IO should NOT be instance of MonadPlus, because it has no zero element. For if it did, the IO action: putStr "hello" >> mzero would not print "hello", which is counterintuitive, and in practice I wouldn't know how to implement it. -Paul P.S. All of the above is in my book :-) Jules Bean wrote:
So, anyone? What are the laws that MonadPlus is supposed to satisfy?
The obvious ones are that if MonadPlus m then for all types a, (m a) should be a monoid. But, what about the others, because IO does not appear to satisfy
a >> mzero == mzero
Jules

G'day all.
Quoting Jules Bean
So, anyone? What are the laws that MonadPlus is supposed to satisfy?
The problem is this "law": m >>= \k -> mzero === mzero I think this "law" is untrue for _all_ MonadPlus instances, and you can trivially check this by setting m to bottom. Cheers, Andrew Bromage

Good point; I suppose the constraint m /= _|_ should be added to the law. ajb@spamcop.net wrote:
The problem is this "law":
m >>= \k -> mzero === mzero
I think this "law" is untrue for _all_ MonadPlus instances, and you can trivially check this by setting m to bottom.
Cheers, Andrew Bromage

Hello,
On Tue, 25 Jan 2005 22:49:06 -0500, Paul Hudak
Good point; I suppose the constraint m /= _|_ should be added to the law.
This is not enough, at least in some cases. Consider lists, and m being an infinite list, e.g. [1..] Then we need that the inifinte concatenation of a empty lists gives us the empty list which is not the case. -Iavor
ajb@spamcop.net wrote:
The problem is this "law":
m >>= \k -> mzero === mzero
I think this "law" is untrue for _all_ MonadPlus instances, and you can trivially check this by setting m to bottom.
Cbheers, Andrew Bromage
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

G'day all.
Quoting Iavor Diatchki
This is not enough, at least in some cases. Consider lists, and m being an infinite list, e.g. [1..] Then we need that the inifinte concatenation of a empty lists gives us the empty list which is not the case.
It also doesn't work for monad transformers (e.g. Ralf Hinze's backtracking transformer) when stacked over monads like IO. I say we remove the "law" altogether. It clearly causes problems, and if you use the Hughes/Hinze method for deriving the monads, it turns out that you don't need it anyway. Cheers, Andrew Bromage

In article
So, anyone? What are the laws that MonadPlus is supposed to satisfy?
These are what I think they should be: mplus mzero a = a mplus a mzero = a mplus (mplus a b) c = mplus a (mplus b c) mzero >>= a = mzero (mplus a b) >>= c = mplus (a >>= c) (b >>= c) These are what is found in Martin and Gibbons paper, even as they're wrong that Maybe can follow them. <http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/tactics .pdf> -- Ashley Yakeley, Seattle WA

Ashley Yakeley writes:
In article
, Jules Bean wrote: So, anyone? What are the laws that MonadPlus is supposed to satisfy?
These are what I think they should be:
mplus mzero a = a mplus a mzero = a mplus (mplus a b) c = mplus a (mplus b c) mzero >>= a = mzero (mplus a b) >>= c = mplus (a >>= c) (b >>= c)
These are what is found in Martin and Gibbons paper, even as they're wrong that Maybe can follow them.
<http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/ tactics
..pdf>
Philip Wadler listed those as the laws he "would usually insist on" in a
1997 message[1].
[1] http://www.dcs.gla.ac.uk/mail-www/haskell/msg00057.html
He also mentions two other possible, but problematic, laws:
m >>= \x -> mzero == mzero
m >>= \x -> k x `mplus` h x == m >>= k `mplus` m >>= h
The first doesn't hold when m is bottom. The second doesn't hold for
lists.
--
David Menendez

David Menendez wrote:
Philip Wadler listed those as the laws he "would usually insist on" in a 1997 message[1].
[1] http://www.dcs.gla.ac.uk/mail-www/haskell/msg00057.html
He also mentions two other possible, but problematic, laws:
m >>= \x -> mzero == mzero m >>= \x -> k x `mplus` h x == m >>= k `mplus` m >>= h
The first doesn't hold when m is bottom. The second doesn't hold for lists.
I would like to know what category MonadPlus represents... A Monad is a category where the objects are functors and the operators are id and product both of which are natural transformations... Presumably the 'laws' for a monad can be derived from this statement. I cannot find any reference to MonadPlus in category theory. At a guess I would say that it was the same as a Monad except the operators are id and co-product (or sum)... That would mean the 'laws' would be exactly the same as a Monad, just with (0,+) instead of (1,*)... Keean.

On 26 Jan 2005, at 08:41, Keean Schupke wrote:
I cannot find any reference to MonadPlus in category theory. At a guess I would say that it was the same as a Monad except the operators are id and co-product (or sum)... That would mean the 'laws' would be exactly the same as a Monad, just with (0,+) instead of (1,*)...
I don't know if the categorists have a word for it. It isn't "the same as a Monad except", it's rather "the same as a Monad and also...". Note that translating between the normal categorical point of view and the haskell one is something of a pain since programmers think with Kleisli arrows (computations). A MonadPlus is a Monad T with, in addition, the structure of a monoid on all types T a, satisfying the some conditions. I follow Wadler and use zero and ++ for the monoid. Unit conditions: If you apply a monadic computation (that is, Kleisli arrow) to the zero object you get zero, that there is a special zero computation (that is concretely \x -> zero) which gives you the zero object when you apply it to anything. Compatibility of ++ with computations: The first condition just says that if you apply a computation to the sum of two objects, that should be the same as applying the computation twice, once to each object, and adding the results. (m ++ n) >>= f == (m >>= f) ++ (n >>= f) The two slightly more subtle conditions observe that it is possible to 'lift' the monoid operation to Kleisli arrows, i.e. if you can add objects, then you can add computations (of the same type): (+++) : (a -> m b) -> (a -> m b) -> (a -> m b) \f g x -> f x ++ g x Then you require that if you first add two computations and apply them to a single object, you get the same result as applying the computations separately and adding the results.. m >>= (f +++ g) == (m >>= f) ++ (m >>= g) ----- If these are a common categorical notion then I'd expect them to be called 'additive monads' or something, but I can't immediately track down a reference. If you translate the notion back to the more standard categorical approach, using mu (join) and eta (return), it may be enlightening, but off hand I can't quite see what the rules look like. Jules

On 26 Jan 2005, at 05:57, David Menendez wrote:
Philip Wadler listed those as the laws he "would usually insist on" in a 1997 message[1].
[1] http://www.dcs.gla.ac.uk/mail-www/haskell/msg00057.html
He also mentions two other possible, but problematic, laws:
m >>= \x -> mzero == mzero m >>= \x -> k x `mplus` h x == m >>= k `mplus` m >>= h
The first doesn't hold when m is bottom. The second doesn't hold for lists.
Well I think the issue with bottom is not too upsetting. The second holds 'up to reordering of the elements', I think?. If you consider lists as representing non-deterministic or multiple-valued computation, then it is quite natural to feel comfortable ignoring the ordering. (In effect, using lists as a model for multi-sets, which form a commutative monad?) But it certainly looks like the IO instance for MonadPlus is badly broken. Are there any interesting programming uses of MonadPlus apart from 'calculations returning multiple values'.. i.e. lists/sets/multisets/maybe? Jules

Jules Bean wrote:
Are there any interesting programming uses of MonadPlus apart from 'calculations returning multiple values'.. i.e. lists/sets/multisets/maybe?
Just a minor point ... You mention Maybe in the list above but I would like to wonder whether it is fully appropriate to associate it with "calculations returning multiple values". Depending on what you find interesting, I would like to mention *biased binary choice*. Try the left operand first, if it fails, try the second operand. For instance, this is a key idiom in strategic programming with Strafunski (and has been adopted from Stratego). All in all, this more like "try and catch" or "exception handling" rather than "calculations returning multiple values". Ralf -- Ralf Laemmel VU & CWI, Amsterdam, The Netherlands http://www.cs.vu.nl/~ralf/
participants (8)
-
ajb@spamcop.net
-
Ashley Yakeley
-
David Menendez
-
Iavor Diatchki
-
Jules Bean
-
Keean Schupke
-
Paul Hudak
-
Ralf Laemmel