Tutorial by Examples

A Producer is some monadic action that can yield values for downstream consumption: type Producer b = Proxy X () () b yield :: Monad m => a -> Producer a m () For example: naturals :: Monad m => Producer Int m () naturals = each [1..] -- each is a utility function exported by Pipes ...
A Consumer can only await values from upstream. type Consumer a = Proxy () a () X await :: Monad m => Consumer a m a For example: fancyPrint :: MonadIO m => Consumer String m () fancyPrint = forever $ do numStr <- await liftIO $ putStrLn ("I received: " ++ numStr) ...
Pipes can both await and yield. type Pipe a b = Proxy () a () b This Pipe awaits an Int and converts it to a String: intToStr :: Monad m => Pipe Int String m () intToStr = forever $ await >>= (yield . show)
We use runEffect to run our Pipe: main :: IO () main = do runEffect $ naturalsUntil 10 >-> intToStr >-> fancyPrint Note that runEffect requires an Effect, which is a self-contained Proxy with no inputs or outputs: runEffect :: Monad m => Effect m r -> m r type Effect = Pr...
Use >-> to connect Producers, Consumers and Pipes to compose larger Pipe functions. printNaturals :: MonadIO m => Effect m () printNaturals = naturalsUntil 10 >-> intToStr >-> fancyPrint Producer, Consumer, Pipe, and Effect types are all defined in terms of the general Prox...
pipes's core data type is the Proxy monad transformer. Pipe, Producer, Consumer and so on are defined in terms of Proxy. Since Proxy is a monad transformer, definitions of Pipes take the form of monadic scripts which await and yield values, additionally performing effects from the base monad m.
Pipes supports simple binary communication between a client and a server In this example: a client connects and sends a FirstMessage the server receives and answers DoSomething 0 the client receives and answers DoNothing step 2 and 3 are repeated indefinitely The command data type exchange...

Page 1 of 1