
On Mon, 13 Oct 2008, Andrew Coppin wrote:
Reid Barton wrote:
It's not difficult: the operation is called
mplus :: MyMonad a -> MyMonad a -> MyMonad a
and already exists (assuming the author of ListT has not forgotten to write a MonadPlus instance).
I see... I was under the impression that "mplus" is just any arbitrary binary operation over a given monad. How do you know what it does for a specific monad?
I had imagined the definition of mplus to be similar in spirit to what bind is for a specific monad. i.e. it's part of that monad's strategy for achieving what it does. As for knowing what it does, trial and error, reading API docs and source. :) Something similar to this discussion had come up recently for me, list monad's MonadPlus implementation. We found ourselves doing something like this to model 'use default value if empty' for strings: let foo = case str of [] -> default s -> s Right away I was wishing I could do this: let foo = str `or-if-empty` default If it was a Maybe, this works with mplus: (Just "foo") `mplus` (Just "bar") == Just "foo" Nothing `mplus` (Just "bar") == Just "bar" But not so much for list, mplus just ain't defined that way, instead doing concatination: "foo" `mplus` "bar" == "foobar" "" `mplus` "bar" == "bar" I ended up writing a special mplus' for this (thanks to #haskell!): mplus' :: (MonadPlus m, Eq (m a)) => m a -> m a -> m a mplus' x y | x == mzero = y | otherwise = x "foo" `mplus'` "bar" == "foo" "" `mplus'` "bar" == "bar" -- Dino Morelli email: dino@ui3.info web: http://ui3.info/d/ irc: dino- pubkey: http://ui3.info/d/dino-4AA4F02D-pub.gpg