В его ответ на вопрос "Различие между классами стилей MonadPlus
, Alternative
и Monoid
?" , Эдвард Кметт говорит, что
Кроме того, даже если
Applicative
был суперклассомMonad
, вы всегда нуждаетесь в классеMonadPlus
, потому что подчиняясьempty <*> m = empty
не является достаточно строгим, чтобы доказать, что
empty >>= f = empty
Так что утверждение, что что-то есть
MonadPlus
, сильнее, чем утверждение, что оноAlternative
.
Ясно, что любой прикладной функтор, который не является монадой, автоматически является примером Alternative
, который не является MonadPlus
, но ответ Эдварда Кемца предполагает, что существует монада, которая является Alternative
, но не является MonadPlus
: его empty
и <|>
будут удовлетворять законам Alternative
, 1 но не законы MonadPlus
. 2 Я не могу придумать пример этого сам; кто-нибудь знает об одном?
1 Я не смог найти каноническую ссылку для набора законов Alternative
, но я излагаю, что я считаю, что они примерно на полпути через мой ответ на вопрос "Confused значением класса типа Alternative
и его отношением к другим классам классов" (поиск фразы "правая дистрибутивность" ). Четыре закона, которые, как я полагаю, должны быть выполнены, заключаются в следующем:
- Правильная дистрибутивность (
<*>
):(f <|> g) <*> a = (f <*> a) <|> (g <*> a)
- Правое поглощение (для
<*>
):empty <*> a = empty
- Левая дистрибутивность (
fmap
):f <$> (a <|> b) = (f <$> a) <|> (f <$> b)
- Левое поглощение (для
fmap
):f <$> empty = empty
Id также счастливо признается, что ему дается более полезный набор законов Alternative
.
2 Я знаю, что есть некоторая двусмысленность в отношении того, чем являются законы MonadPlus
; Я доволен ответом, который использует левый дистрибутив или левый улов, хотя я бы предпочел бы первый вариант.