Skip to content

Instantly share code, notes, and snippets.

@davidallsopp
Created January 29, 2015 15:40
Show Gist options
  • Select an option

  • Save davidallsopp/bb08d1a5b92e4194e815 to your computer and use it in GitHub Desktop.

Select an option

Save davidallsopp/bb08d1a5b92e4194e815 to your computer and use it in GitHub Desktop.
module Conduit1 where
-- From conduit author's tutorial at
-- https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/conduit-overview
-- via https://www.fpcomplete.com/user/jwiegley/conduit-tour
-- needs packages: conduit
import Data.Conduit
-- core data types and primitive operations.
import qualified Data.Conduit.List as CL
-- helper functions for common cases, based on standard Haskell concepts like map and fold.
-- A Source will produce a stream of data values and send them downstream
source :: Source IO Int -- produces a stream of Ints
source = CL.sourceList [1..4]
-- A Sink will consume a stream of data values from upstream and produce a return value.
sink :: Sink String IO () -- consumes a stream of Strings, no result
sink = CL.mapM_ putStrLn
-- The third concept is the Conduit, which consumes a stream of values from upstream
-- and produces a new stream to send downstream.
conduit :: Conduit Int IO String -- converts Ints into Strings
conduit = CL.map $ show . (*2) -- and multiplies by 2 first
-- In order to combine these different components, we have connecting and fusing.
-- The connect operator is $$, and it will combine a Source and Sink, feeding the
-- values produced by the former into the latter, and producing a final result.
main :: IO ()
main = do
source $$ conduit =$ sink
-- alternatively, with the same meaning
source $= conduit $$ sink
-- Fusion, on the other hand, will take two components and generate a new component.
-- For example, =$ can fuse a Conduit and Sink together into a new Sink, which will consume the
-- same values as the original Conduit and produce the same result as the original Sink.
-- The other two fusion operators are
-- $=, which combines a Source and Conduit into a new Source, and
-- =$=, which combines two Conduits into a new Conduit.
--------
-- My simpler example connecting source directly to sink
-- for which we need a new sink that can accept Ints
sink2 :: Sink Int IO () -- consumes a stream of Strings, no result
sink2= CL.mapM_ print
main2 :: IO ()
main2 = source $$ sink2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment