Add Mux
and Demux
#32
Labels
status: needs more info
This issue needs more info before any action can be done.
Mux
and Demux
#32
The
Applicative
typeclass can be presented in a fashion that makes the fact that it is a lax monoidal functor readily apparent:Sometimes when programming with do notation, we end up using a monad to accomplish a task that requires only an applicative. The reason we can get away with this abuse is that every endofunctor on the category of typed functions is commutative strong, and a commutative strong monad is the same thing as a monoidal monad (in the sense of lax monoidal functor).
So whatever you can do with the laxities of a lax monoidal functor, you can do by jiggling around monadic binds, embeddings of values into the functor using the implicit strengths, and the projections products support.
Of course we're not really using the "monad" baggage we've accumulated in our journey through
monad -> trivially commutative strong monad -> monoidal monad
. All we're interested in (in this hypothetical situation) is the fact that the functor is lax monoidal.As a result, we might be unnecessarily precluding the instantiation of our computation at some functor that is lax monoidal (as we need) but not a monad. Fortunately, we have an explicit
Applicative
class that lets us refine our constraints and demand only what we need.An analogous situation sometimes exists when we move from functors to profunctors. It has entered the folklore that an
Arrow
is just aStrong
Category
(give or take a few laws). So we can use this pair of constraints when we need to use familiarArrow
operations like:We can implement this by jiggling around composition and the strengths:
But it turns out that not every profunctor that supports such an operation (if this is indeed all we need) is simultaneously
Strong
andCategory
. Suppose we stick this operation in a class:If you mentally uncurry the arguments, you can see that this is in fact describing a lax monoidal functor. The monoidal codomain is the category of typed functions under the cartesian product structure, and the monoidal domain is the product of the same monoidal category with its own dual.
Now of course whenever we do have both
Strong
andCategory
, we can instantiate this in the obvious way. But considerKleisli m
, which is only aCategory
whenm
is aMonad
. To be aMux
however, all it requires is form
to beApply
:Similarly,
Joker f
does not support an instance ofCategory
at all, but givenApply f
, it too is an instance ofMux
. I haven't done an exhaustive survey of profunctors, these are just the two I needed for my use case, but I would bet there's other examples out there where supportingMux
either admits more instances, or weakens the constraints to provide an instance.So I think it makes sense to add a class like
Mux
topurescript-profunctor
. I'm not sure there's any sensible way to do hierarchy gymnastics to relateStrong
+Category
andMux
(we're pretty lucky that inFunctor
land the strength is trivial and we can have a simpleFunctor -> Applicative -> Monad
hierarchy). It would probably be too big of a breaking change anyway. At any rate, it's not too hard to give aMux
instance usingsplitStrong
if your profunctor is already aStrong
Category
.It's also worth mentioning that another useful family of lax monoidal functors is
Alternative
, which just relates the product and coproduct structures instead of the product structure to itself:This too has a useful analog in profunctors:
Which for example can be instantiated for
Functor f => Kleisli f
andAlt f => Joker f
.Of course there's other monoidal
Functor
s and theirProfunctor
counterparts (and still more monoidalProfunctors
with noFunctor
counterpart), but they're not as well known.Applicative
andAlternative
are reasonably popular ones, so I think it makes sense to have theirProfunctor
counterparts available.I don't have a good name for these, but for completeness, here's the subclasses that round out the analogy to
Apply <-> Applicative
andAlt <-> Alternative
:The text was updated successfully, but these errors were encountered: