I've been procrastinating on writing this issue for a while because every time I start writing it up it turns into a huge essay. So here is a short version that is missing many details, with the idea that something is better than nothing.
It would be useful to have the following newtypes in the library:
newtype Upstream m r b b' a a' = Upstream { runUpstream :: Proxy a' a b' b m r }
newtype Downstream m r a' a b' b = Downstream { runDownstream :: Proxy a' a b' b m r }
These newtypes are useful because they allow us to witness instances of Profunctor and various subclasses for Upstream m r b b' and Downstream m r a' a. In turn, having these instances is useful because it allows us to apply profunctor optics (type Optic p a b s t = p a b -> p s t) directly to pipes (for example the upstream interface supports an instance of Choice, so we can apply prisms to adapt requests, and the downstream interface supports an instance of Strong, so we can apply lenses to adapt responses).
I've been procrastinating on writing this issue for a while because every time I start writing it up it turns into a huge essay. So here is a short version that is missing many details, with the idea that something is better than nothing.
It would be useful to have the following newtypes in the library:
These newtypes are useful because they allow us to witness instances of
Profunctor
and various subclasses forUpstream m r b b'
andDownstream m r a' a
. In turn, having these instances is useful because it allows us to apply profunctor optics (type Optic p a b s t = p a b -> p s t
) directly to pipes (for example the upstream interface supports an instance ofChoice
, so we can apply prisms to adapt requests, and the downstream interface supports an instance ofStrong
, so we can apply lenses to adapt responses).