@hackage streaming0.1.3.0

an elementary streaming prelude and a general monad transformer for streaming applications.

Streaming.Prelude exports an elementary streaming prelude relating to an elementary source/generator/producer type, Stream (Of a) m r. Streaming exports a much more general type, Stream f m r, which can be used to stream successive distinct steps characterized by any functor f, though we are here interested only in a limited range of cases.

The streaming-io libraries have various devices for dealing with effectful variants of [a] or ([a],r). But it is only with the general type Stream f m r, or some equivalent, that one can hope to stream streams, as one makes lists of lists in the Haskell Prelude and Data.List. Once one sees the necessity of some such type if we are to express a properly streaming equivalent of e.g. > groups :: Ord a => [a] -> [[a]] > chunksOf :: Int -> [a] -> [[a]] and the like, then one will also see that, with it, one is already in possession of a complete elementary streaming library. The present Streaming.Prelude is the simplest streaming library that can replicate anything like the API of the Prelude and Data.List.

The emphasis of the library is on interoperation; for the rest its advantages are: extreme simplicity and re-use of intuitions the user has gathered from mastery of Prelude and Data.List. The two conceptual pre-requisites are some comprehension of monad transformers and some familiarity with 'rank 2 types'.

See the readme below for an explanation, including the examples linked there. Elementary usage can be divined from the ghci examples in Streaming.Prelude and perhaps from this rough beginning of a tutorial Note also the streaming bytestring and streaming utils packages.

The simplest form of interoperation with pipes is accomplished with this isomorphism:

Pipes.unfoldr Streaming.next        :: Stream (Of a) m r   -> Producer a m r
Streaming.unfoldr Pipes.next        :: Producer a m r      -> Stream (Of a) m r

Interoperation with io-streams is thus:

Streaming.reread IOStreams.read     :: InputStream a       -> Stream (Of a) IO ()
IOStreams.unfoldM Streaming.uncons  :: Stream (Of a) IO () -> IO (InputStream a)

A simple exit to conduit would be, e.g.:

Conduit.unfoldM Streaming.uncons    :: Stream (Of a) m ()  -> Source m a

These conversions should never be more expensive than a single >-> or =$=. Further points of comparison are discussed in the readme below.

Here are the results of some microbenchmarks based on the benchmarks included in the machines package: