В его ответ на вопрос "Различие между классами стилей 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; Я доволен ответом, который использует левый дистрибутив или левый улов, хотя я бы предпочел бы первый вариант.