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 upstream`b`

and`b'`

are channels for communication with downstream- the primed type variables
`a'`

and`b'`

are requests (i.e. the data travels upstream)`a'`

our request to upstream`b'`

is downstream’s request to us

- the unprimed type variables
`a`

and`b`

are responses (i.e. the data travels downstream)`a`

is upstream’s response to us`b`

is our response to downstream

thus

`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`