Я думаю, что идея этого заключается в том, что Maybe
должен иметь семантику, которая на самом деле только должным образом выражается Option
: она берет любую полугруппу и делает из нее моноид, добавив Nothing
в качестве специального «free mempty». То есть на самом деле экземпляры должны быть
instance Semigroup a => Semigroup (Maybe a) where
Nothing <> a = a
a <> Nothing = a
Just x <> Just y = Just $ x <> y
instance <b>Semigroup</b> a => Monoid (Maybe a) where
mappend = (<>)
mempty = Nothing
Это аналогично тому, как []
дает свободный моноид над любым типом, добавляя как mempty
, так и <>
.
Конечно, для этого требуется, чтобы класс Semigroup
был в base
, чего не было до недавнего времени.
Следствием этого является то, что mempty
становится явно сопоставимым с шаблоном, поскольку по параметризации он не может зависеть от содержимого типа.
На практике этот экземпляр, возможно, более полезен, чем тот, который вы предлагаете, потому что, как заметил Люк, он уже охватывается экземпляром Applicative
, поэтому вы можете легко написать liftA2 (<>)
и pure mempty
. Конечно, стандартный экземпляр также уже охватывается экземпляром Alternative
, но Alternative/MonadPlus
всегда считался немного хакерским, уступая более математически безупречным Semigroup
, Monoid
, Functor
и Applicative
.