distributive
distributive copied to clipboard
Add Applicative and/or Monad superclasses to Distributive?
They are implied by the theory.
This is pretty surprising to me, since some datatypes which currently have Distributive
instances do not have Monad
instances! For example, Compose
from transformers
.
We could likely leave off with just Applicative
, and not do the Monad
.
(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.
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?
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.
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.
Oh, and all Distributive
instances are also MonadFix
s:
mfixDistributive :: Distributive m => (a -> m a) -> m a
mfixDistributive = fmap fix . distribute
The current plan is to package a "Dist" newtype that can be used via Deriving Via to get access to all of these instances for your data type if you want them, but to not require them as superclasses, to maintain compatibility with things like Compose.
On Fri, Oct 5, 2018 at 4:10 AM Zemyla [email protected] wrote:
Oh, and all Distributive instances are also MonadFixs:
mfixDistributive :: Distributive m => (a -> m a) -> m a mfixDistributive = fmap fix . distribute
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ekmett/distributive/issues/12#issuecomment-427281997, or mute the thread https://github.com/notifications/unsubscribe-auth/AASmEbnKg6qVZpI56ct05ghPLSsPtuefks5uhxPegaJpZM4Gvksn .