[Haskell-cafe] Still stacking monad transformers

Dino Morelli dino at ui3.info
Mon Oct 13 14:15:36 EDT 2008


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 at ui3.info  web: http://ui3.info/d/  irc: dino-
pubkey: http://ui3.info/d/dino-4AA4F02D-pub.gpg


More information about the Haskell-Cafe mailing list