optional definition

David Feuer david.feuer at gmail.com
Fri Sep 6 22:35:40 UTC 2019


When you have a MonadPlus instance satisfying the left distribution law [*]:

    (m <|> n) >>= k =  (m >>= k) <|> (n >>= k)

then

    (Just <$> m <|> pure Nothing) >>= k
      = (Just <$> m >>= k) <|> (pure Nothing >>= k)
      = (m >>= k . Just) <|> k Nothing

    (pure Nothing <|> Just <$> m) >>= k
      = k Nothing <|> (m >>= k . Just)

These look pretty similar, so there's no one obviously correct choice. You
could imagine using one to indicate that you prefer to include the optional
part, but that you're okay without it, and the other to indicate that you
only want to include the optional part if necessary.

Suppose, instead, that you have an Alternative instance that satisfies the
left catch law:

     pure x <|> m = pure x

This is very common for parsers that don't backtrack by default, along with
types like Maybe and IO. Now

    pure Nothing <|> Just <$> m = pure Nothing

Oops! That's not useful at all!

Now, let's look at another important practical matter. Lots of real code in
the wild uses `optional`. Almost all of this code would break if the
semantics were changed. So there is basically no chance that will ever
happen. You could make an argument for including the other version too, but
I don't yet see a compelling use case.

[*]
https://en.wikibooks.org/wiki/Haskell/Alternative_and_MonadPlus#Other_suggested_laws

On Thu, Sep 5, 2019, 10:10 PM Dannyu NDos <ndospark320 at gmail.com> wrote:

> I once used `traverse optional` combined with `catMaybes`. For example:
>
> Prelude Control.Applicative Data.Maybe> catMaybes <$> traverse optional
> [[1,2],[3]]
> [[1,3],[1],[2,3],[2],[3],[]]
>
> This is totally out of order. I think a more natural output is:
>
> [[],[3],[1],[1,3],[2],[2,3]]
>
> 2019년 9월 1일 (일) 오후 11:23, Edward Kmett <ekmett at gmail.com>님이 작성:
>
>> It would also render the combinator useless for its normal purpose.
>>
>> optional is used mostly to try to run a parser and to either succeed with
>> its  result (wrapped in a Just) or _failing that_ to just  return Nothing
>> and carry on.
>>
>> For monads like parsec, the first parse is the one that gets returned, so
>> the definition isn't symmetric in behavior.
>>
>> -Edward
>>
>> On Sun, Sep 1, 2019 at 2:28 AM Dannyu NDos <ndospark320 at gmail.com> wrote:
>>
>>> The current 'one or none' definition breaks the order of elements.
>>>
>>> It is more Ord-friendly to define it as 'none or one'.
>>> _______________________________________________
>>> Libraries mailing list
>>> Libraries at haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>
>> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20190906/c6b86753/attachment.html>


More information about the Libraries mailing list