pipes-3.3.0: Compositional pipelines

Safe HaskellTrustworthy




This is an internal module, meaning that it is unsafe to import unless you understand the risks.

This module provides the fast proxy implementation, which achieves its speed by weakening the monad transformer laws. These laws do not hold if you can pattern match on the constructors, as the following counter-example illustrates:

 lift . return = M . return . Pure

 return = Pure

 lift . return /= return

The monad transformer laws do hold when viewed through the safe API exported from Control.Proxy.

Also, you really should not use the constructors anyway, let alone the concrete type and instead you should stick to the Proxy type class API. This not only ensures that your code does not violate the monad transformer laws, but also guarantees that it works with the other proxy implementations and with any proxy transformers.



data ProxyFast a' a b' b m r Source

A ProxyFast communicates with an upstream interface and a downstream interface.

The type variables signify:

  • a' - The request supplied to the upstream interface
  • a - The response provided by the upstream interface
  • b' - The request supplied by the downstream interface
  • b - The response provided to the downstream interface
  • m - The base monad
  • r - The final return value


Request a' (a -> ProxyFast a' a b' b m r) 
Respond b (b' -> ProxyFast a' a b' b m r) 
M (m (ProxyFast a' a b' b m r)) 
Pure r 


ProxyInternal ProxyFast 
Proxy ProxyFast 
MFunctor (ProxyFast a' a b' b) 
MonadTrans (ProxyFast a' a b' b)

Only satisfies monad transformer laws modulo observe

Monad m => Monad (ProxyFast a' a b' b m) 
Monad m => Functor (ProxyFast a' a b' b m) 
Monad m => Applicative (ProxyFast a' a b' b m) 
MonadIO m => MonadIO (ProxyFast a' a b' b m) 

Run Sessions

The following commands run self-sufficient proxies, converting them back to the base monad.

These are the only functions specific to the ProxyFast type. Everything else programs generically over the Proxy type class.

Use runProxyK if you are running proxies nested within proxies. It provides a Kleisli arrow as its result that you can pass to another runProxy / runProxyK command.

runProxy :: Monad m => (() -> ProxyFast a' () () b m r) -> m rSource

Run a self-sufficient ProxyFast Kleisli arrow, converting it back to the base monad

runProxyK :: Monad m => (q -> ProxyFast a' () () b m r) -> q -> m rSource

Run a self-sufficient ProxyFast Kleisli arrow, converting it back to a Kleisli arrow in the base monad


observe :: Monad m => ProxyFast a' a b' b m r -> ProxyFast a' a b' b m rSource

The monad transformer laws are correct when viewed through the observe function:

 observe (lift (return r)) = observe (return r)

 observe (lift (m >>= f)) = observe (lift m >>= lift . f)

This correctness comes at a moderate cost to performance, so use this function sparingly or else you would be better off using Control.Proxy.Core.Correct.

You do not need to use this function if you use the safe API exported from Control.Proxy, which does not export any functions or constructors that can violate the monad transformer laws.