Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Applicative and/or Monad superclasses to Distributive? #12

Open
ekmett opened this issue Dec 6, 2015 · 8 comments
Open

Add Applicative and/or Monad superclasses to Distributive? #12

ekmett opened this issue Dec 6, 2015 · 8 comments

Comments

@ekmett
Copy link
Owner

ekmett commented Dec 6, 2015

They are implied by the theory.

@RyanGlScott
Copy link
Collaborator

This is pretty surprising to me, since some datatypes which currently have Distributive instances do not have Monad instances! For example, Compose from transformers.

@ekmett
Copy link
Owner Author

ekmett commented Dec 8, 2015

We could likely leave off with just Applicative, and not do the Monad.

@ekmett
Copy link
Owner Author

ekmett commented Dec 8, 2015

(and Compose does have that instance.)

The problem is that Distributive isn't strong enough to 'zip' despite the conditions necessary for the existence of an instance saying it should be able to.

@RyanGlScott
Copy link
Collaborator

But that still feels funny to me, since the documentation in adjunctions claims that every Distributive instance admits a Representable instance, which gives rise to an implementation of bind. Does adjunctions' bind not guarantee adherence to the Monad laws?

The problem is that Distributive isn't strong enough to 'zip' despite the conditions necessary for the existence of an instance saying it should be able to.

It isn't?

@ekmett
Copy link
Owner Author

ekmett commented Dec 8, 2015

Representable is strong enough. Distributive doesn't let you know what the representation is.

I'd like more things to be able to work with just a Haskell-98 distributive constraint.

The bind in adjunctions guarantees adherence to the Monad laws. However it isn't suitable for Compose as there are potentially multiple instances of Monad for Compose f g depending on the properties of f and g. e.g. left adjoints also compose, so do any pair of functors with a distributive law (MaybeT, EitherT, ReaderT, WriterT all come from these) or an absorption law, etc.

So my goal is to be able to keep as many instances as possible while amping up the power of Distributive to where it can actually be used in a non-linear situation.

@Zemyla
Copy link

Zemyla commented Nov 28, 2017

Any Functor that is both Applicative and Distributive is also a Monad:

bindDistributive :: (Applicative m, Distributive m) => m a -> (a -> m b) -> m b
bindDistributive m f = m <**> distribute f

It won't let you define the Monad instance for Compose, but you could probably write a newtype wrapper for it.

@Zemyla
Copy link

Zemyla commented Oct 5, 2018

Oh, and all Distributive instances are also MonadFixs:

mfixDistributive :: Distributive m => (a -> m a) -> m a
mfixDistributive = fmap fix . distribute

@ekmett
Copy link
Owner Author

ekmett commented Oct 5, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants