úÎY¡VÛ)      !"#$%&'(Safe-345INA computation which only   s and never  s.A computation which only   s and never  sA  is a computation which can < an intermediate value downstream and suspend execution; and A a value from upstream, deferring execution until it is received.Moreover, individual ®s may be freely composed into larger ones, so long as their types match. Thus, one may write small, reusable building blocks and construct efficient stream process pipelines.¬Since a much better engineered, more popular, and decidedly more mature library already uses the term "pipes" I have opted instead to think of my work as a series of tubes.w is the union of unary functions and binary products into a single type, here defined with a Boehm-Berarducci encoding.)This type is equivalent to the following:  data TubeF a b k = Await (a -> k) -- :: (a -> k) -> TubeF a b k | Yield (b , k) -- :: (b , k) -> TubeF a b k tThe type signatures for the two value constructors should bear a strong resemblance to the actual type signature of J. Instead of encoding tubes as structures which build up when composed, a K is a control flow mechanism which picks one of two provided continuations.ePeople using this library should never have to contend with these details but it is worth mentioning.!Constructor for sink computations #Constructor for source computations This performs a neat trick: a  with a return type a will be turned into a new  containing the underlying  value.In this way the  and  functions can replace the ()k return value with a continuation and recursively traverse the computation until a final result is reached.   is shorter than , and who knows, maybe it'll change some day (Command to wait for a new value upstream "Command to send a value downstream<Connect a task to a continuation yielding another task; see "Compose two tubes into a new tube. Enumerate  .ed values into a continuation, creating a new Infix version of Convert a list to a Insert a value into a )Implementation of " but without the type constraints. Connects a  to a , finishing when either the  is exhausted or the  terminates.*+ )    *+ )SafeIN ,"Used in the case of a specialized O type and we know for certain a particular case will never actually be called.>Continuously relays any values it receives. Iteratee identity.:Transforms all incoming values according to some function.Refuses to yield the first n values it receives.-Yields only values satisfying some predicate.DTerminates the stream upon receiving a value violating the predicateRelay only the first n elements of a stream.)Taps the next value from a source, maybe.Strict left-fold of a stream. Note that the actual return type of the source is not relevant, only the intermediate yield type. Similar to 3 except it explicitly marks the stream as exhausted Source of -Cs from stdin. This is mostly for debugging / ghci example purposes. Sink for -Cs to stdout. This is mostly for debugging / ghci example purposes. ., step function initial valuefinal transformation stream source   .,Safe-479/±Lovingly stolen from Dan Piponi and David Laing. This models a poor man's adjunction: it allows adjoint functors to essentially annihilate one another and produce a final value.cIf this or something equivalent turns up in a separate package I will happily switch to using that.$A $ is the dual to a  : where a 5 is a computation manipulating a stream of values, a $m can be situated on either end of a tube to both insert values when requested and handle any yielded results.One interesting use of a $ is to feed data to a 0, collecting the result as well as unused input: û import Data.Functor.Identity p :: [a] -> Pump (Maybe a) x Identity [a] p inp = pump (return inp) (wa -> case (extract wa) of [] -> (Nothing, wa) x:xs -> (Just x, return xs)) const -- a ÿ° that stops after 5 loops, or when input is exhausted add5 :: Sink (Maybe Int) IO Int add5 = loop 0 5 where loop acc ct = if 0 == ct then return acc else do mn <- await maybe (return acc) (n -> loop (acc+n) (ct - 1)) mn result :: IO ([Int], Int) result = runPump (curry id) (p [1..10]) add5 -- ([6,7,8,9,10],15) $hs are still being investigated by the author so if you come up with something interesting, please share!% Creates a $ for a z using a comonadic seed value, a function to give it more data upon request, and a function to handle any yielded results.Values received from the d may be altered and sent back into the tube, hence this mechanism does act like something of a pump.&Pull a value from a $, along with the rest of the $.'Send a value into a $$, effectively re-seeding the stream.(Given a suitably matching  and $/, you can use the latter to execute the former./0 !"#$%&'1(2345 !"#$%&'( $ !"#%&'( /0 !"#$%&'1(2345All-encompassing module.1(c) 2014, 2015 Gatlin Johnson <gatlin@niltag.net>GPL-3gatlin@niltag.net experimentalSafe'  !"#$%&'('  $ !"#%'&(6     !"#$%&'(()*+,-./012234516789:;<=tubes_8dG9MSndcp97N91HSMf66LTubes Tubes.Core Tubes.Util Tubes.Pumptrans_3eG64VdP2vzGjP6wJiCp5XControl.Monad.Trans.Classliftfree_KK4wRIzDy168X97wpxlOT9Control.Monad.Trans.FreerunFreeTSinkSourceTubeTubeFrunTawaitFyieldFliftTrunawaityield>-><for~>each-<|>catmapdropfilter takeWhiletakeunyieldreduceeverypromptdisplayPumpFrecvFsendFPumppumprecvsendrunPump\|>fixdivergebaseGHC.BaseStringPairingpair pairEffect$fPairingPumpFTubeF$fPairing(,)(->)$fPairing(->)(,)$fPairingIdentityIdentity