Strictness of Semigroup instance for Maybe

Donnacha Oisín Kidney mail at doisinkidney.com
Tue May 22 21:57:29 UTC 2018


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 <http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Semigroup.html#t:First> and Data.Monoid.First <http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Monoid.html#t: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/ <https://www.reddit.com/r/haskell/comments/8lbzan/semigroup_maybe_too_strict/>) and was encouraged to post it here.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20180522/52ea1a12/attachment.html>


More information about the Libraries mailing list