# Why is Maybe's Semigroup instance biased towards Just and the Monoid uses Nothing as its empty element?

• A+
Category：Languages

`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.