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:... and Data.Monoid.First http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Monoid.html#t:Fir...: >>> 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.