Я пытаюсь понять мотивацию MonadPlus
. Почему это необходимо, если уже есть классы Monad
и Monoid
?
Конечно, экземпляры Monoid
являются конкретными типами, тогда как экземпляры Monad
требуют одного параметра типа. (См. Monoid vs MonadPlus для получения полезного объяснения.) Но вы не могли бы переписать ограничение типа
(MonadPlus m) => ...
как комбинация Monad
и Monoid
?
(Monad m, Monoid (m a)) => ...
Возьмем, например, функцию guard
из Control.Monad
. Его реализация:
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
Мне удалось реализовать его, используя только Monad
и Monoid
:
guard' :: (Monad m, Monoid (m ())) => Bool -> m ()
guard' True = return ()
guard' False = mempty
Может кто-то прояснить реальную разницу между MonadPlus
и Monad
+ Monoid
?