@@ -19,9 +19,15 @@
1919-- Streaming and concurrency together enable expressing reactive applications
2020-- conveniently. See 'Streamly.Examples' for a simple SDL based FRP example.
2121--
22−-- In this tutorial we will go over the basic concepts and how to use the
23−-- library. For examples and other ways to use the library see
24−-- the module @Streamly.Examples@ as well.
22+-- Streamly streams are very much like the Haskell lists and most of the
23+-- functions that work on lists have a counterpart that works on streams.
24+-- However, streamly streams can be generated, consumed or combined
25+-- concurrently. In this tutorial we will go over the basic concepts and how to
26+-- use the library. The documentation of @Streamly@ module has more details on
27+-- core APIs. For more APIs for constructing, folding, filtering, mapping and
28+-- zipping etc. see the documentation of @Streamly.Prelude@ module. For
29+-- examples and other ways to use the library see the module
30+-- @Streamly.Examples@ as well.
2531
2632module Streamly.Tutorial
2733 (
@@ -34,28 +40,28 @@ module Streamly.Tutorial
3440 -- ** Eliminating Streams
3541 -- $eliminating
3642
37− -- * Folding Streams
38− -- $folding
43+ -- * Combining Streams
44+ -- $combining
3945
40− -- * Semigroup Style Composition
46+ -- ** Semigroup Style
4147 -- $semigroup
4248
43− -- ** Serial composition ('<>')
49+ -- *** Serial composition ('<>')
4450 -- $serial
4551
46− -- ** Async composition ('<|')
52+ -- *** Async composition ('<|')
4753 -- $parallel
4854
49− -- ** Interleaved composition ('<=>')
55+ -- *** Interleaved composition ('<=>')
5056 -- $interleaved
5157
52− -- ** Parallel composition ('<|>')
58+ -- *** Fair Concurrent composition ('<|>')
5359 -- $fairParallel
5460
55− -- ** Custom composition
61+ -- *** Custom composition
5662 -- $custom
5763
58− -- * Monoid Style composition
64+ -- ** Monoid Style
5965 -- $monoid
6066
6167 -- * Transforming Streams
@@ -64,16 +70,16 @@ module Streamly.Tutorial
6470 -- ** Monad
6571 -- $monad
6672
67− -- *** Serial Iterations ('StreamT')
73+ -- *** Serial Composition ('StreamT')
6874 -- $regularSerial
6975
70− -- *** Concurrent Iterations ('AsyncT')
76+ -- *** Async Composition ('AsyncT')
7177 -- $concurrentNesting
7278
73− -- *** Interleaved Iterations ('InterleavedT')
79+ -- *** Interleaved Composition ('InterleavedT')
7480 -- $interleavedNesting
7581
76− -- *** Fairly Concurrent Iterations ('ParallelT')
82+ -- *** Fair Concurrent Composition ('ParallelT')
7783 -- $fairlyConcurrentNesting
7884
7985 -- *** Exercise
@@ -85,9 +91,6 @@ module Streamly.Tutorial
8591 -- ** Functor
8692 -- $functor
8793
88− -- * Summary of Compositions
89− -- $compositionSummary
90−
9194 -- * Zipping Streams
9295 -- $zipping
9396
@@ -97,6 +100,9 @@ module Streamly.Tutorial
97100 -- ** Parallel Zipping
98101 -- $parallelzip
99102
103+ -- * Summary of Compositions
104+ -- $compositionSummary
105+
100106 -- * Concurrent Programming Examples
101107 -- $concurrent
102108
@@ -153,6 +159,9 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
153159-- @
154160-- return 1 <> return 2 <> return 3 :: StreamT IO Int
155161-- @
162+--
163+-- For more ways to construct or generate a stream see the module
164+-- @Streamly.Prelude@.
156165
157166-- $eliminating
158167--
@@ -181,7 +190,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
181190-- print xs
182191-- @
183192--
184−-- For other ways to eliminate a stream see the module @Streamly.Prelude@.
193+-- For other ways to eliminate or fold a stream see the module
194+-- @Streamly.Prelude@.
185195
186196-- $semigroup
187197-- Streams of the same type can be combined into a composite stream in many
@@ -577,20 +587,29 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
577587
578588-- $functor
579589--
580−-- The simplest transformation on a stream is mapping a function on
581−-- all elements of the stream using 'fmap'.
590+-- 'fmap' transforms a stream by mapping a function on all elements of the
591+-- stream. The functor instance of each stream type defines 'fmap' to be
592+-- precisely the same as 'liftM', and therefore 'fmap' is always serial
593+-- irrespective of the type. For concurrent mapping, alternative versions of
594+-- 'fmap', namely, 'asyncMap' and 'parMap' are provided.
582595--
583596-- @
584597-- import Streamly
585598--
586599-- main = (toList $ serially $ fmap show $ each [1..10]) >>= print
587600-- @
601+--
602+-- Also see the 'mapM' and 'sequence' functions for mapping actions, in the
603+-- @Streamly.Prelude@ module.
588604
589605-- $applicative
590606--
591−-- Applicative is a special case of monad and behaves just like the monadic
592−-- composition. The following example runs all iterations serially and takes a
593−-- total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
607+-- Applicative is precisely the same as the 'ap' operation of 'Monad'. For
608+-- zipping and parallel applicatives separate types 'ZipStream' and 'ZipAsync'
609+-- are provided.
610+--
611+-- The following example runs all iterations serially and takes a total 17
612+-- seconds (1 + 3 + 4 + 2 + 3 + 4):
594613--
595614-- @
596615-- import Streamly
@@ -661,9 +680,6 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
661680-- [(1,3),(2,3),(1,4),(2,4)]
662681-- @
663682
664−-- $folding
665−-- Folds
666−
667683-- $compositionSummary
668684--
669685-- The following table summarizes the types for monadic compositions and the
@@ -690,11 +706,12 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
690706-- streams are combined together using a zip function producing a new
691707-- stream of outputs. Two different types are provided for serial and
692708-- concurrent zipping. These types provide an applicative instance that zips
693−-- the argument streams.
709+-- the argument streams. Also see the zipping function in the @Streamly.Prelude@
710+-- module.
694711
695712-- $serialzip
696713--
697−-- 'StreamZip' zips streams serially:
714+-- 'ZipStream' zips streams serially:
698715--
699716-- @
700717-- import Streamly
@@ -721,7 +738,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
721738
722739-- $parallelzip
723740--
724−-- 'AsyncZip' zips streams concurrently:
741+-- 'ZipAsync' zips streams concurrently:
725742--
726743-- @
727744-- import Streamly
@@ -764,7 +781,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
764781-- import Data.List (sum)
765782--
766783-- main = do
767−-- squares \<- toList $ serially $ foldMapWith (<|) (\x -\> return $ x * x) [1..100]
784+-- squares \<- toList $ serially $ forEachWith (<|) [1..100] $ \\x -\> return $ x * x
768785-- print $ sum squares
769786-- @
770787--
@@ -779,8 +796,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
779796--
780797-- main = do
781798-- z \<- toList $ asyncly $ do
782−-- xsq \<- foldMapWith (\<|) (\\x -> return $ x * x) [1..100]
783−-- ysq \<- foldMapWith (\<|) (\\x -> return $ x * x) [1..100]
799+-- xsq \<- forEachWith (\<|) [1..100] $ \\x -> return $ x * x
800+-- ysq \<- forEachWith (\<|) [1..100] $ \\x -> return $ x * x
784801-- return $ sqrt (xsq + ysq)
785802-- print $ sum z
786803-- @