Description
I proposed MonadZero originally, so it feels somehow appropriate that I’m going to be the one to argue for its demise.
Anyway, as noted in #51, the MonadZero annihilation law empty >>= f = empty
is automatically satisfied for any law-abiding monad, due to parametricity: while evaluating empty >>= f
, the function f
can’t ever be called, since that would require empty
to produce a value, which means that empty >>= f
must be the same as empty >>= pure
, which by the monad laws is just empty
.
As far as I’m aware, the only place we’re using MonadZero is in the definition of guard
. However, I’d argue that the Alternative annihilation law empty <*> f = empty
already gives us enough to ensure that guard
behaves sensibly. Haskell seems to agree, with its guard
only requiring Alternative.
(Note: The Alternative annihilation law isn’t redundant: for a type which isn’t a monad, the effects of the second argument of <*>
could be performed before the first).
Therefore, I propose we do the following:
- Add a deprecation notice to the MonadZero class
- Change
guard
to only require Alternative - Change MonadPlus to have Monad and Alternative superclasses instead of MonadZero
- In a subsequent breaking release, remove MonadZero.