3-- Copyright : (c) 2017 Harendra Kumar
6-- Maintainer : harendra.kumar@gmail.com
7-- Stability : experimental
21 -- * Product Style Composition
28 -- * Zip Style Composition
33 -- * Sum Style Composition
41 -- * Stream Type Adapters
76import Streamly.Streams
77import Data.Semigroup (Semigroup(..))
78import Control.Applicative (Alternative(..))
79import Control.Monad (MonadPlus(..))
80import Control.Monad.IO.Class (MonadIO (..))
81import Control.Monad.Trans.Class (MonadTrans (..))
85-- Streamly provides a monad transformer that extends the product style
86-- composition of monads to streams of many elements of the same type; it is a
87-- functional programming equivalent of nested loops from imperative
88-- programming. Composing each element in one stream with each element in the
89-- other stream generalizes the monadic product of single elements. You can
90-- think of the IO monad as a special case of the more general @StreamT IO@
91-- monad; with single element streams. List transformers and logic programming
92-- monads also provide a similar product style composition of streams, however
93-- streamly generalizes it with the time dimension; allowing streams to be
94-- composed in an asynchronous and concurrent fashion in many different ways.
95-- It also provides multiple alternative ways of composing streams e.g.
96-- serial, interleaved or concurrent.
98-- The seemingly simple addition of asynchronicity and concurrency to product
99-- style streaming composition unifies a number of disparate abstractions into
100-- one powerful and elegant abstraction. A wide variety of programming
101-- problems can be solved elegantly with this abstraction. In particular, it
102-- unifies three major programming domains namely non-deterministic (logic)
103-- programming, concurrent programming and functional reactive programming. In
104-- other words, you can do everything with this one abstraction that you could
105-- with list transformers (e.g.
106-- <https://hackage.haskell.org/package/list-t list-t>), logic programming
107-- monads (e.g. <https://hackage.haskell.org/package/logict logict>),
108-- streaming libraries (a lot of what
109-- <https://hackage.haskell.org/package/conduit conduit> or
110-- <https://hackage.haskell.org/package/pipes pipes> can do), concurrency
111-- libraries (e.g. <https://hackage.haskell.org/package/async async>) and FRP
112-- libraries (e.g. <https://hackage.haskell.org/package/Yampa Yampa> or
113-- <https://hackage.haskell.org/package/reflex reflex>).
117-- Streamly provides six distinct stream types i.e. 'StreamT', 'InterleavedT',
118-- 'AsyncT' and 'ParallelT', 'ZipStream' and 'ZipAsync', each representing a
119-- stream of elements. All these types have the same underlying representation
120-- and can be adapted from one to another using type adaptor combinators
121-- described later. Each of these types belongs to the 'Streaming' type class
122-- which helps converting the specific type to and from the underlying generic
125-- The types 'StreamT', 'InterleavedT', 'AsyncT' and 'ParallelT' are 'Monad'
126-- transformers with the monadic bind operation combining streams in a product
127-- style in much the same way as a list monad or a list transformer i.e. each
128-- element from one stream is combined with every element of the other stream.
129-- However, the applicative and monadic composition of these types differ in
130-- terms of the ordering and time sequence in which the elements from two
131-- streams are combined. 'StreamT' and 'InterleavedT' compose streams serially
132-- whereas 'AsyncT' and 'ParallelT' are their concurrent counterparts. See the
133-- documentation of the respective types for more details.
135-- The types 'ZipStream' and 'ZipAsync' provide 'Applicative' instances to zip
136-- two streams together i.e. each element in one stream is combined with the
137-- corresponding element in the other stream. 'ZipStream' generates the streams
138-- being zipped serially whereas 'ZipAsync' produces both the elements being
139-- zipped concurrently.
141-- Two streams of the same type can be combined using a sum style composition
142-- to generate a stream of the same type where the output stream would contain
143-- all elements of both the streams. However, the sequence in which the
144-- elements in the resulting stream are produced depends on the combining
145-- operator. Four distinct sum style operators, '<>', '<=>', '<|' and '<|>'
146-- combine two streams in different ways, each corresponding to the one of the
147-- four ways of combining monadically. See the respective section below for
150-- Concurrent composition types 'AsyncT', 'ParallelT', 'ZipAsync' and
151-- concurrent composition operators '<|' and '<|>' require the underlying monad
152-- of the streaming monad transformer to be 'MonadAsync'.
154-- For more details please see the "Streamly.Tutorial" and "Streamly.Examples"
155-- (the latter is available only when built with the 'examples' build flag).
157-- A simple inline example here illustrating applicative, monad and alternative
162-- Streams that compose serially or non-concurrently come in two flavors i.e.
163-- 'StreamT' and 'InterleavedT'. Both of these serial flavors have
164-- corresponding concurrent equivalents, those are 'AsyncT' and 'ParallelT'
169-- 'ZipStream' and 'ZipAsync', provide 'Applicative' instances for zipping the
170-- corresponding elements of two streams together. Note that these types are
175-- Just like product style composition there are four distinct ways to combine
176-- streams in sum style each directly corresponding to one of the product style
179-- The standard semigroup append '<>' operator appends two streams serially,
180-- this style corresponds to the 'StreamT' style of monadic composition.
183-- main = ('toList' . 'serially' $ (return 1 <> return 2) <> (return 3 <> return 4)) >>= print
189-- The standard 'Alternative' operator '<|>' fairly interleaves two streams in
190-- parallel, this operator corresponds to the 'ParallelT' style.
193-- main = ('toList' . 'serially' $ (return 1 <> return 2) \<|\> (return 3 <> return 4)) >>= print
199-- Unlike '<|', this operator cannot be used to fold infinite containers since
200-- that might accumulate too many partially drained streams. To be clear, it
201-- can combine infinite streams but not infinite number of streams.
203-- Two additional sum style composition operators that streamly introduces are
208-- Code using streamly is usually written such that it is agnostic of any
209-- specific streaming type. We use a type variable (polymorphic type) with the
210-- 'Streaming' class constraint. Finally, when running the monad we can specify
211-- the actual type that we want to use to interpret the code. However, in
212-- certain cases we may want to use a specific type to force a certain type of
213-- composition. These combinators can be used to convert the stream types from
214-- one to another at no cost as all the types have the same underlying
217-- If you see an @ambiguous type variable@ error then most likely it is because
218-- you have not specified the stream type. You either need a type annotation or
219-- one of the following combinators to specify what type of stream you mean.
224-- main = ('toList' $ (return 1 <> return 2)) >>= print
227-- will result in a type error like this:
230-- Ambiguous type variable ‘t0’ arising from a use of ...
233-- To fix the error just tell 'toList' what kind of stream are we feeding it:
236-- main = ('toList' $ 'serially' $ (return 1 <> return 2)) >>= print
239-- main = ('toList' $ (return 1 <> return 2 :: StreamT IO Int)) >>= print
242-- Note that using the combinators is easier as you do not have to think about
243-- the specific types, they are just inferred.
248-- These are some convenience functions to fold any 'Foldable' container using
249-- one of the sum composition operators to convert it into a streamly stream.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list