
Ashley Yakeley wrote:
In article
, "S. Alexander Jacobson" wrote: I assume there is a standard name for this class/function:
instance Foo [] where foo [] = mzero foo (x:_) = return x
instance Foo (Maybe x) where foo Nothing = mzero foo Just x = return x
Surely they are incomplete monad definitions (has a return but no bind)...
I don't believe so. I had to write my own classes to do this sort of thing.
This is also a good opporunity to point out an ambiguity in the standard MonadPlus class. All instances satisfy these:
mplus mzero a = a mplus a mzero = a
But only some instances (such as []) satisfy this:
(mplus a b) >>= c = mplus (a >>= c) (b >>= c)
Other instances (IO, Maybe) satisfy this:
mplus (return a) b = return a
I think mplus should be separated into two functions. This code shows the difference a bit more clearly:
do b <- mplus (return True) (return False) if b then mzero else return ()
For the first kind this is the same as "return ()", for the second kind it's the same as "mzero".
But isnt the point of Monad plus, that to have a 'zero' implies failure (a normal monad cannot fail) - and failure implies choice (a `mplus` b) is a if a succeeds or b if a fails and b succeeds,or mzero if both fail. if you look at your first identity: mplus mzero a = a mplus a mzero = a This fits the above description, but I don't see how the following can be true: (mplus a b) >>= c = mplus (a >>= c) (b >>= c) The LHS says (if a fails run b) then run c. The RHS says if (a then c) fails run (b then c) Finally, mplus (return a) b = return a Is obvious because "return a" is not "mzero", so it is true for all Monads that can fail. Or have I missed the point? Keean.