Skip to content

Interplay between Apply and Bind #158

Closed
@joneshf

Description

@joneshf

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions