Safe Haskell  SafeInferred 

A Proxy
request
s input from upstream and respond
s with output to
downstream.
For an extended tutorial, consult Control.Proxy.Tutorial.
 data Proxy a' a b' b m r
 data C
 type Server req resp = Proxy C () req resp
 type Client req resp = Proxy req resp () C
 type Session = Proxy C () () C
 runProxy :: Monad m => (() > Proxy a' () () b m r) > m r
 runProxyK :: Monad m => (() > Proxy a () () b m r) > () > m r
 runSession :: Monad m => (() > Session m r) > m r
 runSessionK :: Monad m => (() > Session m r) > () > m r
 discard :: Monad m => () > Proxy () a () C m r
 ignore :: Monad m => a > Proxy C () a () m r
Types
data Proxy a' a b' b m r Source
A Proxy
communicates with an upstream interface and a downstream
interface.
The type variables of Proxy req_a resp_a req_b resp_b m r
signify:

req_a
 The request supplied to the upstream interface 
resp_a
 The response provided by the upstream interface 
req_b
 The request supplied by the downstream interface 
resp_b
 The response provided to the downstream interface 
m
 The base monad 
r
 The final return value
Request a' (a > Proxy a' a b' b m r)  
Respond b (b' > Proxy a' a b' b m r)  
M (m (Proxy a' a b' b m r))  
Pure r 
Interact Proxy  
Channel Proxy  
MonadTrans (Proxy a' a b' b)  
MFunctor (Proxy a' a b' b)  
Monad m => Monad (Proxy a' a b' b m)  
Monad m => Functor (Proxy a' a b' b m)  
(Functor (Proxy a' a b' b m), Monad m) => Applicative (Proxy a' a b' b m)  
(Monad (Proxy a' a b' b m), MonadIO m) => MonadIO (Proxy a' a b' b m) 
Run Sessions
I provide two ways to run proxies:

runProxy
, which discards unhandled output from either end 
runSession
, which type restricts its argument to ensure no loose ends
Both functions require that the input to each end is trivially satisfiable,
(i.e. ()
).
I recommend runProxy
for most use cases since it is more convenient.
runSession
only accepts sessions that do not send unhandled data flying
off each end, which provides the following benefits:
 It prevents against accidental data loss.
 It protects against silent failures
 It prevents wastefully draining a scarce resource by gratuitously driving it to completion
However, this restriction means that you must either duplicate every utility
function to specialize them to the endpoint positions (which I do not do),
or explicitly close loose ends using the discard
and ignore
proxies:
runSession $ discard << p << ignore
Use the 'K
' versions of each command if you are running sessions nested
within sessions. They provide a Kleisli arrow as their result suitable to
be passed to another runProxy
/ runSession
command.
runProxy :: Monad m => (() > Proxy a' () () b m r) > m rSource
Run a selfsufficient Proxy
Kleisli arrow, converting it back to the base
monad
runProxyK :: Monad m => (() > Proxy a () () b m r) > () > m rSource
Run a selfsufficient Proxy
Kleisli arrow, converting it back to a Kleisli
arrow in the base monad
runSession :: Monad m => (() > Session m r) > m rSource
Run a selfcontained Session
Kleisli arrow, converting it back to the base
monad
runSessionK :: Monad m => (() > Session m r) > () > m rSource
Run a selfcontained Session
Kleisli arrow, converting it back to a
Kleisli arrow in the base monad