[Haskell-cafe] Still stacking monad transformers

Tillmann Rendel rendel at daimi.au.dk
Mon Oct 13 16:17:22 EDT 2008


Dino Morelli wrote:
> 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"

The difference between Maybe-style MonadPlus and List-style MonadPlus is
discussed on

   http://www.haskell.org/haskellwiki/MonadPlus_reform_proposal.

With that proposal, you could use morelse with both Maybe and lists.
Personally, I would like to call these beasts <|> (for Maybe-style
mplus) and <+> (for List-style mplus). One could even have

   a <| b = a <|> pure b
   a <+ b = a <+> pure b
   a +> b = pure a <+> b

in the style of <* and *>. Note that I assume Applicative as a
superclass of Monad, while I'm talking about a better world anyway.

That said, I would consider using something like the <+> sketched here
for Strings as a hack, because I do not see Strings as Chars under the
List functor, even if they technically may be exactly that. Since "abc"
does not represent multiple results, I don't think "" should represent
failure.

Instead, I would wrap optional strings in Maybe, and then use fromMaybe
to handle the default values:

   fromMaybe "bar" (Just "foo") = "foo"
   fromMaybe "bar" Nothing      = "bar"

Now, with the operators sketched above, fromMaybe = flip (<|), so one
could use

   Just "foo" <| "bar" = "foo"
   Nothing    <| "bar" = "bar"

which seems to closely correspond to what you want.

   Tillmann




More information about the Haskell-Cafe mailing list