-
Notifications
You must be signed in to change notification settings - Fork 92
Description
On the heels of #141, we now have that the Apply and Bind instances for a data type have to agree when that data type also has a Monad. It seems like we're still missing something.
With the laws as they're written, you can have a Bind instance for a data type that doesn't agree with its Apply instance, so long as said data type does not also define a Monad instance. I think that's not right. I think we want to make sure that the Apply and Bind instances agree.
A real data type that could sneak a lawful Bind instance in as the laws are now is Data.Validation.Semigroup.V:
instance bindV :: (Semigroup a) => Bind (V a) where
bind = flip (unV invalid)I'm pretty sure that definition is associative, but it will "short-circuit" at the first invalid case. That doesn't agree with the Apply instance (which accumulates invalid cases).
I'm proposing that we change ap to something like:
ap :: forall a b f. Bind f => f (a -> b) -> f a -> f b
ap f a = bind f (mapFlipped a)And move the Applicative Superclass law to Bind (probably change the name of the law as well).
Thoughts?