| Safe Haskell | Safe |
|---|---|
| Language | Haskell98 |
Control.Proxy.Core
Contents
Description
A Proxy requests input from upstream and responds 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 interfaceresp_a- The response provided by the upstream interfacereq_b- The request supplied by the downstream interfaceresp_b- The response provided to the downstream interfacem- The base monadr- The final return value
Constructors
| 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 |
Instances
| Interact Proxy Source # | |
| Channel Proxy Source # | |
| MonadTrans (Proxy a' a b' b) Source # | |
| MFunctor (Proxy a' a b' b) Source # | |
| Monad m => Monad (Proxy a' a b' b m) Source # | |
| Monad m => Functor (Proxy a' a b' b m) Source # | |
| Monad m => Applicative (Proxy a' a b' b m) Source # | |
| MonadIO m => MonadIO (Proxy a' a b' b m) Source # | |
Run Sessions
I provide two ways to run proxies:
runProxy, which discards unhandled output from either endrunSession, 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 end-point 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 r Source #
Run a self-sufficient Proxy Kleisli arrow, converting it back to the base
monad
runProxyK :: Monad m => (() -> Proxy a () () b m r) -> () -> m r Source #
Run a self-sufficient Proxy Kleisli arrow, converting it back to a Kleisli
arrow in the base monad
runSession :: Monad m => (() -> Session m r) -> m r Source #
Run a self-contained Session Kleisli arrow, converting it back to the base
monad
runSessionK :: Monad m => (() -> Session m r) -> () -> m r Source #
Run a self-contained Session Kleisli arrow, converting it back to a
Kleisli arrow in the base monad