úÎföaôU      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTSafe1A self-contained pipeline that is ready to be runA pipe that consumes valuesA pipe that produces valuesThe type variables of  Pipe a b m r signify:a1 - The type of input received from upstream pipesb3 - The type of output delivered to downstream pipesm - The base monadr - The type of the return value A self-contained , ready to be run by s never   anything or   to anything. Client req resp sends requests of type req$ and receives responses of type resp.s only   and never   to anything. Server req resp receives requests of type req! and sends responses of type resp.s only   and never   anything. A " converts one interface to anotherThe base functor for the  type  : input from upstream, passing an argument with the request request a' passes a'Z as a parameter to upstream that upstream can use to decide what response to return.  - binds the response to its return value.  : with an output for downstream and bind downstream's next   respond b satisfies a downstream   by supplying the value b.   blocks until downstream  7s a new value and binds the argument from the next   as its return value. ]Compose two proxies, satisfying all requests from downstream with responses from upstreamCorresponds to (U)/(V) from Control.Category ]Compose two proxies, satisfying all requests from downstream with responses from upstreamCorresponds to (W) from Control.Category  acts like a 'T'ransparent Z, passing all requests further upstream, and passing all responses further downstream.Corresponds to X from Control.Category Run a self-contained &, converting it back to the base monadDiscard all responsesIgnore all requests-Compose a 'K'leisli arrow with itself foreverWait for input from upstream! blocks until input is available #Convert a pure function into a pipeDeliver output downstream: restores control back downstream and binds the result to . Corresponds to (V)/(U) from Control.CategoryCorresponds to (W) from Control.CategoryCorresponds to X from Control.CategoryRun the 8 monad transformer, converting it back to the base monad Y    Y 9 9 9 9 SafeSafe " s form a Z/ instance when you rearrange the type variables1A self-contained pipeline that is ready to be run A pipe that consumes values!A pipe that produces values"The base type for pipesa1 - The type of input received from upstream pipesb3 - The type of output delivered to downstream pipesm - The base monadr - The type of the return value#The base functor for the " type&Wait for input from upstream.&/ blocks until input is available from upstream.'Deliver output downstream.'8 restores control back upstream and binds the result to &.(#Convert a pure function into a pipe 4pipe f = forever $ do x <- await yield (f x))Corresponds to (V)/(U) from Control.Category*Corresponds to (W) from Control.Category+Corresponds to X from Control.Category,Run the "; monad transformer, converting it back into the base monad., imposes two conditions:9The pipe's input, if any, is trivially satisfiable (i.e. ())The pipe does not ' any outputThe latter restriction makes ,[ less polymorphic than it could be, and I settled on the restriction for three reasons:)It prevents against accidental data loss.aIt prevents wastefully draining a scarce resource by gratuitously demanding values from it.lIt encourages an idiomatic pipe programming style where input is consumed in a structured way using a  .ªIf you believe that discarding output is the appropriate behavior, you can specify this by explicitly feeding your output to a pipe that gratuitously discards it: runPipe $ forever await <+< p !"#$%&'()*+,-. !"#%$&'()*+,#$%"! &'()*+, !"#$%&'()*+,-.)9 *9 SafeDQR/Indexed equivalent to FreeT2Indexed equivalent to FreeF5Indexed equivalent to wrap6Indexed equivalent to liftF /0123456789/0123456234/0156/0123456789Safe%&QR:> s form a Z/ instance when you rearrange the type variables=A self-contained > that is ready to be run>A > is like a " with an indexed input end:b - The type of the >s outputm - The base monadi' - The initial index of the input end (Epen or Dlosed)j% - The final index of the input end (Epen or Dlosed)r - The return value?4Base functor for a pipe that can close its input endb - Output typex - Next stepi - Current step's indexC?Index representing an open input end, receiving values of type Maybe aD%Index representing a closed input endE?Index representing an open input end, receiving values of type aF@% the most current finalizer for this > alongside the valueGA" a value from upstream, returning [ if upstream terminatesHB9 the input end, calling the finalizers of every upstream >II. a value upstream alongside an empty finalizerJJ; a value from upstream and terminate if upstream terminatesK catchD m p calls the finalizer m if a downstream > terminates before p finishes.L catchF m p calls the finalizer m if any > terminates before p finishes.M finallyD m p calls the finalizer m if a downstream > terminates before p finishes or if p completes normally.N finallyF m p calls the finalizer m if any > terminates before p finishes or if p completes normally.OCorresponds to (V)/(U) from Control.CategoryPCorresponds to (W) from Control.CategoryQCorresponds to X from Control.CategoryRRun the >9 monad transformer, converting it back to the base monad.R is the > equivalent to ,# and requires a self-contained =.!:;<=>?@ABCDEFGHIJKLMN\]^_`OPQRaST:;<=>?@ABCDEFGHIJKLMNOPQRDEC?@AB>=FGHIJKLMNOPQ:;<R:;<=>?@ABCDEFGHIJKLMN\]^_`OPQRaSTO9 P9 SafeSafeb      !"#$$%   &'( !")*++,-./01234556789(':;<=>?@ABCDEFGHIJKIJLIJMIJNOIJPIQRSTUVWXY"pipes-2.3.0-7l57khu9HYL4pjZW8kBwRQ Control.Proxy Control.PipeControl.IMonad.Trans.Free Control.FrameControl.Proxy.TutorialControl.Frame.TutorialControl.Pipe.TutorialPipelineConsumerProducerPipeSessionClientServerProxyProxyFRequestRespondrequestrespond<-<>->idT runSessiondiscardignoreforeverKawaitpipeyield<+<>+>idPrunPipe$fFunctorProxyFPipeCunPipeCPipeFAwaitYield$fCategoryTYPEPipeC$fFunctorPipeFIFreeT runIFreeTIFreeFReturnWrapwrapliftF$fIMonadTransTYPEIFreeT$fIMonadTYPEIFreeT$fIFunctorTYPETYPEIFreeTFrameCunFrameCStackFrameFrameFCloseMCOyieldFawaitFclosecatchDcatchFfinallyDfinallyFidFrunFrame$fCategoryTYPEFrameC$fIFunctorTYPETYPEFrameFbaseControl.Category.<<<>>>id runSession'CategoryGHC.BaseNothing<~<<~|heapstackwarn runFrame'