Strictness of Semigroup instance for Maybe

Tikhon Jelvis tikhon at jelv.is
Tue May 22 23:57:32 UTC 2018


I think the extra laziness makes sense here—it matches the behavior of
common functions like &&. My general expectation is that functions are as
lazy as they can be and, in the case of operators with two arguments, that
evaluation goes left-to-right. (Again like &&.)

On Tue, May 22, 2018 at 4:37 PM, David Feuer <david.feuer at gmail.com> wrote:

> I think extra laziness here would be a bit surprising.
>
> On Tue, May 22, 2018 at 5:57 PM, Donnacha Oisín Kidney
> <mail at doisinkidney.com> wrote:
> > The current semigroup instance  for Maybe looks like  this:
> >
> >     instance Semigroup a => Semigroup (Maybe a) where
> >         Nothing <> b       = b
> >         a       <> Nothing = a
> >         Just a  <> Just b  = Just (a <> b)
> >
> > However, it could be lazier:
> >
> >     instance Semigroup a => Semigroup (Maybe a) where
> >         Nothing <> b = b
> >         Just a  <> b = Just (maybe a (a<>) b)
> >
> > This causes different behaviour for Data.Semigroup.First and
> > Data.Monoid.First:
> >
> >     >>>  Data.Monoid.getFirst . foldMap pure $ [1..]
> >     Just 1
> >     >>>  fmap Data.Semigroup.getFirst . Data.Semigroup.getOption .
> foldMap
> > (pure.pure) $ [1..]
> >     _|_
> >
> > A different definition for `Option` gets back the old behaviour:
> >
> >     newtype LeftOption a = LeftOption { getLeftOption :: Maybe a }
> >
> >     instance Semigroup a => Semigroup (LeftOption a) where
> >       LeftOption Nothing <> ys = ys
> >       LeftOption (Just x) <> LeftOption ys = LeftOption (Just (maybe x
> (x<>)
> > ys))
> >
> >     instance Semigroup a => Monoid (LeftOption a) where
> >       mempty = LeftOption Nothing
> >       mappend = (<>)
> >
> >     >>> fmap Data.Semigroup.getFirst . getLeftOption . foldMap
> (LeftOption .
> > Just . Data.Semigroup.First) $ [1..]
> >     Just 1
> >
> > Is there any benefit to the extra strictness? Should this be changed?
> >
> > Another consideration is that the definition could equivalently be
> > right-strict, to get the desired behaviour for Last, but I think the
> > left-strict definition probably follows the conventions more.
> >
> > I originally posted this to reddit
> > (https://www.reddit.com/r/haskell/comments/8lbzan/
> semigroup_maybe_too_strict/)
> > and was encouraged to post it here.
> >
> > _______________________________________________
> > 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/20180522/08b1c5c8/attachment.html>


More information about the Libraries mailing list