@@ -9,7 +9,7 @@
9-- Streamly is a general computing framework based on streaming IO. The IO
9-- Streamly is a general computing framework based on streaming IO. The IO
10-- monad and pure lists are a special case of streamly. On one hand, streamly
10-- monad and pure lists are a special case of streamly. On one hand, streamly
11-- extends the lists of pure values to lists of monadic actions, on the other
11-- extends the lists of pure values to lists of monadic actions, on the other
12−-- hand it extends the IO monad with concurrrent non-determinism. In simple
12+-- hand it extends the IO monad with concurrent non-determinism. In simple
13-- imperative terms we can say that streamly extends the IO monad with @for@
13-- imperative terms we can say that streamly extends the IO monad with @for@
14-- loops and nested @for@ loops with concurrency support. You can understand
14-- loops and nested @for@ loops with concurrency support. You can understand
15-- this analogy better once you can go through this tutorial.
15-- this analogy better once you can go through this tutorial.
@@ -199,12 +199,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
200-- $concurrentStreams
200-- $concurrentStreams
202−-- Streams can be generated concurrently, even infnite streams can be generated
202+-- Many stream operations can be done concurrently:
203−-- concurrently using controlled concurrency, streams can be merged
203+--
204+-- * Streams can be generated concurrently.
206+-- * Streams can be merged concurrently.
204−-- concurrently, multiple stages in a streaming pipeline can run concurrently,
208+-- * Multiple stages in a streaming pipeline can run concurrently.
205−-- streams can be mapped concurrently, they can be zipped concurrently, and in
209+--
210+-- * Streams can be mapped and zipped concurrently.
206−-- a monadic composition they combine like a list transformer providing
212+-- * In monadic composition they combine like a list transformer,
207−-- concurrent non-determinism.
213+-- providing concurrent non-determinism.
209-- There are three basic concurrent stream styles, 'Ahead', 'Async', and
215-- There are three basic concurrent stream styles, 'Ahead', 'Async', and
210-- 'Parallel'. The 'Ahead' style streams are similar to 'Serial' except that
216-- 'Parallel'. The 'Ahead' style streams are similar to 'Serial' except that
@@ -244,20 +250,24 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
246-- All these types can be freely inter-converted using type conversion
252-- All these types can be freely inter-converted using type conversion
247−-- combinators or type annotations without any cost, to acheive the desired
253+-- combinators or type annotations, without any cost, to achieve the desired
248−-- composition style. To force a particular type of composition we coerce the
254+-- composition style. To force a particular type of composition, we coerce the
249-- stream type using the corresponding type adapting combinator from
255-- stream type using the corresponding type adapting combinator from
250-- 'serially', 'aheadly', 'asyncly', or 'parallely'. The default stream type
256-- 'serially', 'aheadly', 'asyncly', or 'parallely'. The default stream type
251-- is inferred as 'Serial' unless you change it by using one of the combinators
257-- is inferred as 'Serial' unless you change it by using one of the combinators
252−-- or using a type annotation.
258+-- or by using a type annotation.
254-- $flavors
260-- $flavors
256−-- Streams can be combined using semigroup or monoid composition to form a
262+-- Streams can be combined using '<>' or 'mappend' to form a
257−-- composite stream. Traversal of a composition of streams could be @deep@ or
263+-- composite. Composite streams can be interpreted in a depth first or
264+-- breadth first manner using an appropriate type conversion before
265+-- consumption. Deep (e.g. 'Serial') stream type variants traverse a
258−-- @wide@. Deep goes depth first i.e. each stream is traversed fully before
266+-- composite stream in a depth first manner, such that each stream is
259−-- we traverse the next stream. Wide goes breadth first i.e. one element from
267+-- traversed fully before traversing the next stream. Wide
268+-- (e.g. 'WSerial') stream types traverse it in a breadth first
269+-- manner, such that one element from each stream is traversed before
260−-- each stream is traversed before coming back to the first stream again.
270+-- coming back to the first stream again.
262-- Each stream type has a wide traversal variant prefixed by 'W'. The wide
272-- Each stream type has a wide traversal variant prefixed by 'W'. The wide
263-- variant differs only in the Semigroup\/Monoid, Applicative\/Monad
273-- variant differs only in the Semigroup\/Monoid, Applicative\/Monad
@@ -384,12 +394,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
385-- $generatingConcurrently
395-- $generatingConcurrently
387−-- Monadic construction and generation functions e.g. 'consM', 'unfoldrM',
397+-- Monadic construction and generation functions like 'consM', 'unfoldrM',
388−-- 'replicateM', 'repeatM', 'iterateM' and 'fromFoldableM' etc work
398+-- 'replicateM', 'repeatM', 'iterateM' and 'fromFoldableM' work concurrently
389−-- concurrently when used with appropriate stream type combinator. The pure
399+-- when used with appropriate stream type combinator. The pure versions of
390−-- versions of these APIs are not concurrent, however you can use the monadic
400+-- these APIs are not concurrent, however you can use the monadic versions even
391−-- versions even for pure computations by wrapping the pure value in a monad to
401+-- for pure computations by wrapping the pure value in a monad to get the
392−-- get the concurrent generation capability where required.
402+-- concurrent generation capability where required.
394-- The following code finishes in 3 seconds (6 seconds when serial):
404-- The following code finishes in 3 seconds (6 seconds when serial):
@@ -521,7 +531,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
521-- The 'Semigroup' operation '<>' of the 'Serial' type combines the two streams
531-- The 'Semigroup' operation '<>' of the 'Serial' type combines the two streams
522-- in a /serial depth first/ manner. We use the 'serially' type combinator to
532-- in a /serial depth first/ manner. We use the 'serially' type combinator to
523-- effect 'Serial' style of composition. We can also use an explicit 'Serial'
533-- effect 'Serial' style of composition. We can also use an explicit 'Serial'
524−-- type annotation for the stream to acheive the same effect. However, since
534+-- type annotation for the stream to achieve the same effect. However, since
525-- 'Serial' is the default type unless explicitly specified by using a
535-- 'Serial' is the default type unless explicitly specified by using a
526-- combinator, we can omit using an explicit combinator or type annotation for
536-- combinator, we can omit using an explicit combinator or type annotation for
527-- this style of composition.
537-- this style of composition.
@@ -570,11 +580,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
570-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
580-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
571-- streams in a /serial breadth first/ manner. We use the 'wSerially' type
581-- streams in a /serial breadth first/ manner. We use the 'wSerially' type
572-- combinator to effect 'WSerial' style of composition. We can also use the
582-- combinator to effect 'WSerial' style of composition. We can also use the
573−-- 'WSerial' type annotation for the stream to acheive the same effect.
583+-- 'WSerial' type annotation for the stream to achieve the same effect.
575-- When two streams with multiple elements are combined in this manner, we
585-- When two streams with multiple elements are combined in this manner, we
576-- traverse all the streams in a breadth first manner i.e. one action from each
586-- traverse all the streams in a breadth first manner i.e. one action from each
577−-- stream is peformed and yielded to the resulting stream before we come back
587+-- stream is performed and yielded to the resulting stream before we come back
578-- to the first stream again and so on.
588-- to the first stream again and so on.
579-- The following example prints the sequence 1, 3, 2, 4
589-- The following example prints the sequence 1, 3, 2, 4
@@ -625,7 +635,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
625-- The 'Semigroup' operation '<>' of the 'Ahead' type combines two streams in a
635-- The 'Semigroup' operation '<>' of the 'Ahead' type combines two streams in a
626-- /serial depth first/ manner with concurrent lookahead. We use the 'aheadly'
636-- /serial depth first/ manner with concurrent lookahead. We use the 'aheadly'
627-- type combinator to effect 'Ahead' style of composition. We can also use an
637-- type combinator to effect 'Ahead' style of composition. We can also use an
628−-- explicit 'Ahead' type annotation for the stream to acheive the same effect.
638+-- explicit 'Ahead' type annotation for the stream to achieve the same effect.
630-- When two streams are combined in this manner, the streams are traversed in
640-- When two streams are combined in this manner, the streams are traversed in
631-- depth first manner just like 'Serial', however it can execute the next
641-- depth first manner just like 'Serial', however it can execute the next
@@ -658,7 +668,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
658-- The 'Semigroup' operation '<>' of the 'Async' type combines the two
668-- The 'Semigroup' operation '<>' of the 'Async' type combines the two
659-- streams in a depth first manner with parallel look ahead. We use the
669-- streams in a depth first manner with parallel look ahead. We use the
660-- 'asyncly' type combinator to effect 'Async' style of composition. We
670-- 'asyncly' type combinator to effect 'Async' style of composition. We
661−-- can also use the 'Async' type annotation for the stream type to acheive
671+-- can also use the 'Async' type annotation for the stream type to achieve
662-- the same effect.
672-- the same effect.
664-- When two streams with multiple elements are combined in this manner, the
674-- When two streams with multiple elements are combined in this manner, the
@@ -839,7 +849,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
839-- streams in a fairly concurrent manner with round robin scheduling. We use
849-- streams in a fairly concurrent manner with round robin scheduling. We use
840-- the 'parallely' type combinator to effect 'Parallel' style of composition.
850-- the 'parallely' type combinator to effect 'Parallel' style of composition.
841-- We can also use the 'Parallel' type annotation for the stream type to
851-- We can also use the 'Parallel' type annotation for the stream type to
842−-- acheive the same effect.
852+-- achieve the same effect.
844-- When two streams with multiple elements are combined in this manner, the
854-- When two streams with multiple elements are combined in this manner, the
845-- monadic actions in both the streams are performed concurrently with a fair
855-- monadic actions in both the streams are performed concurrently with a fair
@@ -1274,7 +1284,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1274-- [(1,3),(1,4),(2,3),(2,4)]
1284-- [(1,3),(1,4),(2,3),(2,4)]
1277−-- Similalrly 'WSerial' applicative runs the iterations in an interleaved
1287+-- Similarly 'WSerial' applicative runs the iterations in an interleaved
1278-- order but since it is serial it takes a total of 17 seconds:
1288-- order but since it is serial it takes a total of 17 seconds:
@@ -1306,7 +1316,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1306-- [(1,3),(2,3),(1,4),(2,4)]
1316-- [(1,3),(2,3),(1,4),(2,4)]
1309−-- Similalrly 'WAsync' as well can run the iterations concurrently and
1319+-- Similarly 'WAsync' as well can run the iterations concurrently and
1310-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
1320-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
@@ -1684,7 +1694,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1684-- comparison to transient streamly has a first class streaming interface and
1694-- comparison to transient streamly has a first class streaming interface and
1685-- is a monad transformer that can be used universally in any Haskell monad
1695-- is a monad transformer that can be used universally in any Haskell monad
1686-- transformer stack. Streamly was in fact originally inspired by the
1696-- transformer stack. Streamly was in fact originally inspired by the
1687−-- concurrency implementation in @transient@ though it has no resemblence with
1697+-- concurrency implementation in @transient@ though it has no resemblance with
1688-- that and takes a lazy pull approach versus transient's strict push approach.
1698-- that and takes a lazy pull approach versus transient's strict push approach.
1690-- The non-determinism, concurrency and streaming combination make streamly a
1700-- The non-determinism, concurrency and streaming combination make streamly a