on master help sign in
Spelling fixes + other misc tutorial adjustments
c0bcda8Michael Sloan
src/Streamly/Tutorial.hs+40−30
@@ -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))
199
199
200-- $concurrentStreams
200-- $concurrentStreams
201--
201--
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.
205+--
206+-- * Streams can be merged concurrently.
207+--
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.
211+--
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.
208--
214--
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))
244-- @
250-- @
245--
251--
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.
253
259
254-- $flavors
260-- $flavors
255--
261--
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.
261--
271--
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))
384
394
385-- $generatingConcurrently
395-- $generatingConcurrently
386--
396--
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.
393--
403--
394-- The following code finishes in 3 seconds (6 seconds when serial):
404-- The following code finishes in 3 seconds (6 seconds when serial):
395--
405--
@@ -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.
574--
584--
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
580--
590--
@@ -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.
629--
639--
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.
663--
673--
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.
843--
853--
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)]
1275-- @
1285-- @
1276--
1286--
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:
1279--
1289--
1280-- @
1290-- @
@@ -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)]
1307-- @
1317-- @
1308--
1318--
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):
1311--
1321--
1312-- @
1322-- @
@@ -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.
1689--
1699--
1690-- The non-determinism, concurrency and streaming combination make streamly a
1700-- The non-determinism, concurrency and streaming combination make streamly a
streamly.cabal+2−2
@@ -31,8 +31,8 @@ description:
31 .
31 .
32 For file IO, currently the library provides only one API to stream the lines
32 For file IO, currently the library provides only one API to stream the lines
33 in the file as Strings. Future versions will provide better streaming file
33 in the file as Strings. Future versions will provide better streaming file
34− IO options. Streamly interworks with the popular streaming libraries, see
34+ IO options. Streamly interoperates with the popular streaming libraries, see
35− the interworking section in "Streamly.Tutorial".
35+ the interoperation section in "Streamly.Tutorial".
36 .
36 .
37 Why use streamly?
37 Why use streamly?
38 .
38 .