The following typechecks:
instance (Applicative f, Alternative f, Foldable f) => Monad f where
(>>=) = flip $ \f -> foldr (<|>) empty . fmap f
-- Or equivalently
a >>= b = getAlt . foldMap Alt . fmap b $ a
Is this actually a valid Monad
instance? If yes, why is it not used? If no, does it break any laws or such? I have not proved that the laws hold, but I couldn't find a counterexample either.
This should be a counterexample to the right identity monad law.
Below, we exploit the functor product
Maybe :*: Maybe
fromGHC.Generics
, but it could be inlined, if wished. This is also an applicative, alternative, foldable, and monad. I trust the libraries on these instances to be law-abiding.We then compare the proposed
instance Monad
(the one in the question) to the standard library one. We find that the right identity law is not satisfied for the proposed instance, while it appears to hold (at least in my very limited tests) in the library instance.The
4
is now replaced by3
. I have not tried to explain why, though. I guess it is caused byJust 3 <|> Just 4 = Just 3
.Using the library monad instance, instead, everything looks fine: