concrete functor and monad transformers
#66Alternative and MonadPlus instances for ContT
The laws seem to check out and Codensity
from kan-extensions
has them as well.
Codensity
is the same as ContT
but with a universally qualified return type, so you can not do things like callCC
:
newtype Codensity m a = Codensity { runCodensity :: forall b . (a -> m b) -> m b }
This is what these instances would look like:
instance (Monad m, Alternative m) => Alternative (ContT r m) where
empty = lift empty
ContT mx <|> ContT my = ContT $ \cont -> mx cont <|> my cont
instance (Monad m, Alternative m) => MonadPlus (ContT r m)
- description updated
Ok, actually I this does not honour the right identity of mzero, i.e:
m >> mzero = mzero
. E.g:>>> (`runContT` pure) $ ContT $ \_ -> pure () :: Maybe () Just ()
Alternative
does not have that law though, so that would still be possible. But if you do not want a type that is both aMonad
and anAlternative
but not aMonadPlus
I would understand that.Another question would be whether
empty
should belift empty
orContT $ \_ -> empty
. The former at least satisfies the left identity ofmzero
, but the latter does not require aMonad
constraint onm
.- description updated
That should have been
>>> (`runContT` pure) $ (ContT $ \_ -> pure ()) >> mzero :: Maybe () Just ()
- status set to closed
Closing this issue, as I think these instances are not well behaved enough. Even for
Alternative
I would expectfa *> mzero = mzero
, even if it is not stated in the laws.