- A+

`Maybe`

expresses computations that might not produce a result due to an error. Therefore such computations must be short circuited.

Now `Maybe`

's Semigroup/Monoid instances seem to break with this semantics, because the former is biased towards `Just`

and the latter treats the error case `Nothing`

as its empty element:

`Just "foo" <> Nothing -- Just "foo" Nothing <> Just "bar" -- Just "bar" Just "foo" <> Just "bar" -- Just "foobar" Nothing <> Nothing -- Nothing `

I would expect `Nothing`

for the first two cases.

Here is the alternative implementation (hopefully it is correct/lawful):

`instance Semigroup a => Semigroup (Maybe a) where Nothing <> _ = Nothing _ <> Nothing = Nothing Just a <> Just b = Just (a <> b) instance Monoid a => Monoid (Maybe a) where mempty = Just mempty `

I don't want to say that these alternative instances are better. But they seem useful too. So why was a selection made in the first place instead of leaving the implementation to the user?

Your instance is actually a special case of a much more general instance for applicative functors.

`newtype LiftA f a = LiftA { getLiftA :: f a } instance (Applicative f, Semigroup a) => Semigroup (LiftA f a) where LiftA x <> LiftA y = LiftA $ liftA2 (<>) x y instance (Applicative f, Monoid a) => Monoid (LiftA f a) where mempty = LiftA $ pure mempty `

Which I assumed would be in the standard library somewhere (under a different name probably) but I couldn't find it. But the existence of this general instance could be one reason to choose the library version of `Maybe`

, which is more of `Maybe`

's special power. On the other hand, it's quite nice when your algebraic structures are all coherent with each other; i.e. when a type is an `Applicative`

, use the "`LiftA`

"-style instance whenever possible (on all F-algebra classes).

On the third hand (!), we can't have coherence everywhere, since the library instance agrees with `Maybe`

's `MonadPlus`

instance. This is strikingly parallel to the fact that there are two monoids on natural numbers: addition and multiplication. For numbers, we just picked not to have *any* monoid instance because it's unclear which to use.

In conclusion, I don't know. But maybe this information was helpful.