@hackage streaming0.1.0.16
a free monad transformer optimized for streaming applications
Installation
Dependencies (4)
- base >=4.6 && <5
- mmorph >=1.0 && <1.2
- mtl >=2.1 && <2.3
- transformers >=0.4 && <0.5 Show all…
Dependents (97)
@hackage/prometheus-effect, @hackage/box, @hackage/eventsource-store-specs, @hackage/cabal-scaffold, @hackage/web-rep, @hackage/om-socket, Show all…
Stream can be used wherever
FreeT
is used. The compiler's
standard range of optimizations work better for operations
written in terms of Stream. FreeT f m r / Stream f m r
is of course extremely general, and many functor-general combinators
are exported by the general module Streaming.
Streaming.Prelude is focused on elementary streaming applications.
Here the free iteration of the 'base' functors
(readings of the f in Stream f m r) express
forms of effectful sequence or succession. Some of types in question
appear in the streaming IO libraries under titles like
pipes: Producer a m r, Producer a m (Producer a m r), FreeT (Producer a m) m r io-streams: InputStream a, Generator a r conduit: Source m a, ConduitM () o m r
Streaming.Prelude closely follows Pipes.Prelude, but cleverly omits the pipes:
ghci> S.stdoutLn $ S.take 2 S.stdinLn let's<Enter> let's stream<Enter> stream
And here we do a little connect and resume, as the streaming-io experts call it:
ghci> rest <- S.print $ S.splitAt 3 $ S.each [1..10] 1 2 3 ghci> S.sum rest 49
Somehow, we didn't even need a four-character operator for that, nor advice about best practices! - just ordinary Haskell common sense.
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
(streaming can be mixed with pipes wherever pipes
itself employs Control.Monad.Trans.Free; speedups are frequently
appreciable.) 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 =$=.
At a much more general level, we also of course have interoperation with free:
Free.iterTM Stream.wrap :: FreeT f m a -> Stream f m a Stream.iterTM Free.wrap :: Stream f m a -> FreeT f m a
For some simple ghci examples, see the commentary throughout the Prelude module. For slightly more advanced usage see the commentary in the haddocks of streaming-bytestring and e.g. these replicas of shell-like programs from the io-streams tutorial. Here's a simple streaming GET request with intrinsically streaming byte streams.