When implementing an Alternative f
(or MonadPlus f
) instance, you have to select a monoid over f a
and implement it using empty
and <|>
. For some structures, such as lists, there can be several possibilities. The most natural monoidal operation for lists is their concatenation (with []
being the identity element). Taking the first non-empty element, as you suggest, is also a possibility, but not as natural for lists. Your operation almost ignores the structure (the length) of lists, it only checks if a list is empty or not. And it doesn't add anything new, because this kind of monoidal operation is already available as Maybe
's instance of Alternative
, which is designed to represent (non)empty values.
This is also reflected in the instance of MonadPlus
of []
. As described on HaskellWiki, there are two possible sets of laws for instances of MonadPlus
:
- Monoid + LeftZero + LeftDistribution - statisfied by
[]
- Monoid + LeftZero + LeftCatch - statisfied by
Maybe
, IO
and STM
.
If we chose your implementation of Alternative
and MonadPlus
, then we'd have only instances satisfying ... + LeftCatch
, nothing satisfying LeftDistribution. And again, MonadPlus
of []
wouldn't be very different from MonadPlus
of Maybe
. And we wouldn't have anything that would enable us to solve things like the send+more=money puzzle. So it's much more interesting to choose the mplus
/<|>
of []
to be concatenation.