by Tom Ellis on 29th March 2013
Initially I found it rather hard to understand how the Proxy types from the Pipes library work. This is what I discovered. I’m going to use the ProxyCorrect
type for the examples.
The data definitions are
data ProxyCorrect a' a b' b m r =
Proxy { unProxy :: m (ProxyF a' a b' b r (ProxyCorrect a' a b' b m r)) }
-- | The base functor for the 'ProxyCorrect' type
data ProxyF a' a b' b r x
= Request a' (a -> x)
| Respond b (b' -> x)
| Pure r
Then
a
and a'
are channels for communication with upstreamb
and b'
are channels for communication with downstreama'
and b'
are requests (i.e. the data travels upstream)
a'
our request to upstreamb'
is downstream’s request to usa
and b
are responses (i.e. the data travels downstream)
a
is upstream’s response to usb
is our response to downstreamthus
a'
and b
are what we emit (upstream and downstream respectively)a
and b'
are what we receive (from upstream and downstream respectively)m
is the monad that a'
and b
are generated in. r
is the type of the final return value of the proxy when it terminates.
A crucial point is that
ProxyCorrect a' a b' b m r
is just about to emit a request or response though we don’t know which. If you want a proxy that is ready to receive a request you must use
\b' -> ProxyCorrect a' a b' b m r
and if you want a proxy that is ready to receive a response you must use
\a -> ProxyCorrect a' a b' b m r