on master help sign in
Change the nomenclature of streams
commitc9277a83a76274f4a3ecfa7ab7c5cff5cb02c3c1 authorHarendra Kumar <harendra.kumar@gmail.com> dateSun 13 May 2018, 10:13 (8 years ago) parentce79079
7 files changed+742−690
Changelog.md+20−26 README.md+27−18 src/Streamly.hs+58−66 src/Streamly/Core.hs+40−46 src/Streamly/Prelude.hs+36−52 src/Streamly/Streams.hs+260−278 src/Streamly/Tutorial.hs+301−204
Changelog.md+20−26
@@ -1,7 +1,7 @@
11## 0.2.0
22
33### Breaking changes
4−* Change the semantics of the Semigroup instance for `InterleavedT`, `AsyncT`
4+* Changed the semantics of the Semigroup instance for `InterleavedT`, `AsyncT`
55 and `ParallelT`. The new semantics are as follows:
66 * For `InterleavedT`, `<>` operation interleaves two streams
77 * For `AsyncT`, `<>` now concurrently merges two streams in a left biased
@@ -9,26 +9,26 @@
99 * For `ParallelT`, the `<>` operation now concurrently meges the two streams
1010 in a fairly parallel manner.
1111
12− To adapt to the new changes, replace `<>` with `splice` wherever it is used
12+ To adapt to the new changes, replace `<>` with `serial` wherever it is used
1313 for stream types other than `StreamT`.
1414
1515* Remove the `Alternative` instance. To adapt to this change replace any usage
1616 of `<|>` with `parallel` and `empty` with `nil`.
17−* Stream type now defaults to the `StreamT` type unless explicitly specified
17+* Stream type now defaults to the `SerialT` type unless explicitly specified
1818 using a type combinator or a monomorphic type. This change reduces puzzling
1919 type errors for beginners. It includes the following two changes:
20− * Change the type of all stream elimination functions to use `StreamT`
20+ * Change the type of all stream elimination functions to use `SerialT`
2121 instead of a polymorphic type. This makes sure that the stream type is
2222 always fixed at all exits.
2323 * Change the type combinators (e.g. `parallely`) to only fix the argument
2424 stream type and the output stream type remains polymorphic.
25−
2625 Stream types may have to be changed or type combinators may have to be added
2726 or removed to adapt to this change.
28−* The type `ZipStream` has been redefined to be specialized to IO monad.
29− `ZipStreamM` is now the same as the original `ZipStream` type. You will have
30− to change all occurrences of `ZipStream` to `ZipStreamM`.
3127* Change the type of `foldrM` to make it consistent with `foldrM` in base.
28+* `async` is renamed to `mkAsync` and `async` is now a new API with a different
29+ meaning.
30+* `ZipAsync` is renamed to `ZipAsyncM` and `ZipAsync` is now ZipAsyncM
31+ specialized to the IO Monad.
3232* Remove the `MonadError` instance as it was not working correctly for
3333 parallel compositions. Use `MonadThrow` instead for error propagation.
3434* Remove Num/Fractional/Floating instances as they are not very useful. Use
@@ -36,26 +36,21 @@
3636
3737### Deprecations
3838* Deprecate and rename the following symbols:
39− * `MonadAsync` to `MonadParallel`
4039 * `Streaming` to `IsStream`
4140 * `runStreaming` to `runStream`
42− * `InterleavedT` to `CostreamT`
43− * `AsyncT` to `ParAheadT`
44− * `ZipAsync` to `ZipParallelM`
45− * `serially` to `asStream`
46− * `interleaving` to `asCostream`
47− * `asyncly` to `asParAhead`
48− * `parallely` to `asParallel`
49− * `zipping` to `asZipStream`
50− * `zippingAsync` to `asZipParallel`
51− * `<=>` to `cosplice`
52− * `<|` to `parAhead`
41+ * `StreamT` to `SerialT`
42+ * `InterleavedT` to `WSerialT`
43+ * `ZipStream` to `ZipSerialM`
44+ * `ZipAsync` to `ZipAsyncM`
45+ * `interleaving` to `wSerially`
46+ * `zipping` to `zipSerially`
47+ * `zippingAsync` to `zipAsyncly`
48+ * `<=>` to `wSerial`
49+ * `<|` to `async`
5350 * `each` to `fromFoldable`
5451 * `scan` to `scanx`
5552 * `foldl` to `foldx`
5653 * `foldlM` to `foldxM`
57− * `zipAsyncWith` to `zipParallelWith`
58− * `zipAsyncWithM` to `zipParallelWithM`
5954* Deprecate the following symbols for future removal:
6055 * `runStreamT`
6156 * `runInterleavedT`
@@ -72,11 +67,10 @@
7267 * `scanl'` strict left scan
7368 * `foldl'` strict left fold
7469 * `foldlM'` strict left fold with a monadic fold function
75− * `splice` run two streams serially one after the other
70+ * `serial` run two streams serially one after the other
71+ * `async` run two streams asynchronously
7672 * `parallel` run two streams in parallel (replaces `<|>`)
77− * `CoparAhead` stream type for BFS version of ahead parallel composition
78− * `coparAhead` ahead parallel composition of two streams
79− * `asCoparAhead` type combinator for CoparAhead stream type
73+ * `WAsyncT` stream type for BFS version of `AsyncT` composition
8074* Add simpler stream types that are specialized to the IO monad
8175
8276## 0.1.2
README.md+27−18
@@ -32,8 +32,8 @@ the functionality of list transformer libraries like `pipes` or
3232[list-t](https://hackage.haskell.org/package/list-t) and also the logic
3333programming library [logict](https://hackage.haskell.org/package/logict). On
3434the concurrency side, it subsumes the functionality of the
35−[async](https://hackage.haskell.org/package/async) package. Because it streams
36−and supports concurrency we can write FRP applications similar in concept to
35+[async](https://hackage.haskell.org/package/async) package. Because it supports
36+streaming with concurrency we can write FRP applications similar in concept to
3737[Yampa](https://hackage.haskell.org/package/Yampa) or
3838[reflex](https://hackage.haskell.org/package/reflex). To understand the
3939streaming library ecosystem and where streamly fits in you may want to read
@@ -57,7 +57,7 @@ Why use streamly?
5757 [streaming-benchmarks](https://github.com/composewell/streaming-benchmarks)
5858 for a comparison of popular streaming libraries on micro-benchmarks.
5959
60− For more information:
60+ For more information, see:
6161
6262 * [Streamly.Tutorial](https://hackage.haskell.org/package/streamly/docs/Streamly-Tutorial.html) module in the haddock documentation for a detailed introduction
6363 * [examples](https://github.com/composewell/streamly/tree/master/examples) directory in the package for some simple practical examples
@@ -68,9 +68,9 @@ Unlike `pipes` or `conduit` and like `vector` and `streaming` `streamly`
6868composes stream data instead of stream processors (functions). A stream is
6969just like a list and is explicitly passed around to functions that process the
7070stream. Therefore, no special operator is needed to join stages in a streaming
71−pipeline, just a forward (`$`) or reverse (`&`) function application operator
72−is enough. Combinators are provided in `Streamly.Prelude` to transform or fold
73−streams.
71+pipeline, just the standard forward (`$`) or reverse (`&`) function application
72+operator is enough. Combinators are provided in `Streamly.Prelude` to
73+transform or fold streams.
7474
7575```haskell
7676import Streamly
@@ -90,8 +90,8 @@ main = runStream $
9090
9191Semigroup and Monoid instances can be used to fold streams serially or
9292concurrently. In the following example we are composing ten actions in the
93−stream each with a delay of 1 to 10 seconds. Since all the actions are
94−concurrent we see one output printed every second:
93+stream each with a delay of 1 to 10 seconds, respectively. Since all the
94+actions are concurrent we see one output printed every second:
9595
9696``` haskell
9797import Streamly
@@ -102,7 +102,9 @@ main = S.toList $ parallely $ foldMap delay [1..10]
102102 where delay n = S.once $ threadDelay (n * 1000000) >> print n
103103```
104104
105−Streams can be combined together in many ways (see the tutorial for more ways):
105+Streams can be combined together in many ways. We are providing some examples
106+below, see the tutorial for more ways. We will use the following `delay`
107+function in the examples to demonstrate the concurrency aspects:
106108
107109``` haskell
108110import Streamly
@@ -160,29 +162,36 @@ main = runStream loops
160162
161163## Concurrent Nested Loops
162164
163−To run the above code with demand-driven concurrency i.e. each iteration in the
164−loops can run concurrently depending on the consumer rate:
165+To run the above code with demand-driven depth first concurrency i.e. each
166+iteration in the loops can run concurrently depending on the consumer rate:
165167
166168``` haskell
167−main = runStream $ coparallely $ loops
169+main = runStream $ asyncly $ loops
168170```
169171
170−To run it with round-robin parallelism:
172+To run it with demand driven breadth first concurrency:
173+
174+``` haskell
175+main = runStream $ wAsyncly $ loops
176+```
177+
178+To run it with strict concurrency irrespective of demand:
171179
172180``` haskell
173181main = runStream $ parallely $ loops
174182```
175183
176−To run it serially but interleaving the outer and inner loop iterations:
184+To run it serially but interleaving the outer and inner loop iterations
185+(breadth first serial):
177186
178187``` haskell
179−main = runStream $ costreamly $ loops
188+main = runStream $ wSerially $ loops
180189```
181190
182191## Magical Concurrency
183192
184193Streams can perform semigroup (<>) and monadic bind (>>=) operations
185−concurrently using combinators like `coparallelly`, `parallelly`. For example,
194+concurrently using combinators like `asyncly`, `parallelly`. For example,
186195to concurrently generate squares of a stream of numbers and then concurrently
187196sum the square roots of all combinations of two streams:
188197
@@ -191,7 +200,7 @@ import Streamly
191200import qualified Streamly.Prelude as S
192201
193202main = do
194− s <- S.sum $ coparallely $ do
203+ s <- S.sum $ asyncly $ do
195204 -- Each square is performed concurrently, (<>) is concurrent
196205 x2 <- foldMap (\x -> return $ x * x) [1..100]
197206 y2 <- foldMap (\y -> return $ x * x) [1..100]
@@ -207,7 +216,7 @@ example, to concurrently list the contents of a directory tree recursively:
207216import Path.IO (listDir, getCurrentDir)
208217import Streamly
209218
210−main = runStream $ coparallely $ getCurrentDir >>= readdir
219+main = runStream $ asyncly $ getCurrentDir >>= readdir
211220 where readdir d = do
212221 (dirs, files) <- S.once $ listDir d
213222 S.once $ mapM_ putStrLn $ map show files
src/Streamly.hs+58−66
@@ -15,18 +15,18 @@
1515-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
1616-- appending streams of arbitrary length is scalable and inexpensive.
1717--
18−-- The basic stream type is 'Stream', it represents a sequence of IO actions,
19−-- and is a 'Monad'. The type 'StreamT' is a monad transformer that can
20−-- represent a sequence of actions in an arbitrary monad. The type 'Stream' is
21−-- in fact a synonym for @StreamT IO@. There are a few more types similar to
22−-- 'StreamT', all of them represent a stream and differ only in the
23−-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Stream'
24−-- and 'Costream' types compose serially whereas 'ParAhead' and 'CoparAhead'
18+-- The basic stream type is 'Serial', it represents a sequence of IO actions,
19+-- and is a 'Monad'. The type 'SerialT' is a monad transformer that can
20+-- represent a sequence of actions in an arbitrary monad. The type 'Serial' is
21+-- in fact a synonym for @SerialT IO@. There are a few more types similar to
22+-- 'SerialT', all of them represent a stream and differ only in the
23+-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Serial'
24+-- and 'WSerial' types compose serially whereas 'Async' and 'WAsync'
2525-- types compose concurrently. All these types can be freely inter-converted
2626-- using type combinators without any cost. You can freely switch to any type
2727-- of composition at any point in the program. When no type annotation or
2828-- explicit stream type combinators are used, the default stream type is
29−-- inferred as 'Stream'.
29+-- inferred as 'Serial'.
3030--
3131-- Here is a simple console echo program example:
3232--
@@ -57,60 +57,60 @@
5757
5858module Streamly
5959 (
60− MonadParallel
60+ MonadAsync
6161
6262 -- * Stream transformers
6363 -- ** Serial Streams
6464 -- $serial
65− , StreamT
66− , CostreamT
65+ , SerialT
66+ , WSerialT
6767
6868 -- ** Parallel Streams
69− -- $parAhead
70− , ParAheadT
71− , CoparAheadT
69+ -- $async
70+ , AsyncT
71+ , WAsyncT
7272 , ParallelT
7373
7474 -- ** Zipping Streams
7575 -- $zipping
76− , ZipStreamM
77− , ZipParallelM
76+ , ZipSerialM
77+ , ZipAsyncM
7878
7979 -- * Polymorphic Sum Operations
8080 -- $sum
81− , splice
82− , cosplice
83− , parAhead
84− , coparAhead
81+ , serial
82+ , wSerial
83+ , async
84+ , wAsync
8585 , parallel
8686
8787 -- * Stream Type Adapters
8888 -- $adapters
8989 , IsStream
9090
91− , asStream
92− , asCostream
93− , asParAhead
94− , asCoparAhead
95− , asParallel
96− , asZipStream
97− , asZipParallel
91+ , serially
92+ , wSerially
93+ , asyncly
94+ , wAsyncly
95+ , parallely
96+ , zipSerially
97+ , zipAsyncly
9898 , adapt
9999
100100 -- * IO Streams
101− , Stream
102− , Costream
103− , ParAhead
104− , CoparAhead
101+ , Serial
102+ , WSerial
103+ , Async
104+ , WAsync
105105 , Parallel
106− , ZipStream
107− , ZipParallel
106+ , ZipSerial
107+ , ZipAsync
108108
109109 -- * Running Streams
110110 , runStream
111111
112112 -- * Transformation
113− , async
113+ , mkAsync
114114
115115 -- * Polymorphic Fold Utilities
116116 -- $foldutils
@@ -121,22 +121,18 @@ module Streamly
121121 -- * Re-exports
122122 , Semigroup (..)
123123 -- * Deprecated
124− , MonadAsync
125124 , Streaming
126125 , runStreaming
127126 , runStreamT
128127 , runInterleavedT
129− , runParallelT
130− , runZipAsync
131128 , runAsyncT
129+ , runParallelT
132130 , runZipStream
131+ , runZipAsync
132+ , StreamT
133133 , InterleavedT
134− , AsyncT
135− , ZipAsync
136− , serially
134+ , ZipStream
137135 , interleaving
138− , asyncly
139− , parallely
140136 , zipping
141137 , zippingAsync
142138 , (<=>)
@@ -150,28 +146,24 @@ import Data.Semigroup (Semigroup(..))
150146-- $serial
151147--
152148-- Serial streams compose serially or non-concurrently. In a composed stream,
153−-- at any point of time only one constituent stream runs and yields an element.
154−-- The two serial stream types 'StreamT' and 'CostreamT' differ in how they
155−-- merge streams together in a 'Semigroup' or 'Monad' composition. As these
156−-- streams are serial, the sequence of items in a composed stream can be solely
157−-- determined by the position of elements in the consituent streams.
158−
159−-- $parAhead
160−--
161−-- Parallel ahead streams compose in an ahead parallel manner. In a composed stream, at
162−-- any point of time more than one stream can run concurrently and yield
163−-- elements. The two parallel ahead types 'ParAheadT' and 'coParAheadT' differ in how
164−-- they merge streams together in 'Semigroup' or 'Monad' compositions. As
165−-- these streams compose concurrently, the sequence of items in a composed
166−-- stream cannot be determined by the position of elements in the constituent
167−-- streams. The elements are yielded by the composed stream as they are
168−-- generated by the constituent streams on a first come first serve basis.
169−-- Therefore, on each run the stream may yield elements in a different sequence
170−-- depending on the delays introduced by scheduling.
149+-- each action is executed only after the prvious action has finished. The two
150+-- serial stream types 'SerialT' and 'WSerialT' differ in how they traverse the
151+-- streams in a 'Semigroup' or 'Monad' composition.
152+
153+-- $async
154+--
155+-- The async style streams execute actions asynchronously and consume the
156+-- outputs as well asynchronously. In a composed stream, at any point of time
157+-- more than one stream can run concurrently and yield elements. The elements
158+-- are yielded by the composed stream as they are generated by the constituent
159+-- streams on a first come first serve basis. Therefore, on each run the
160+-- stream may yield elements in a different sequence depending on the delays
161+-- introduced by scheduling. The two async types 'AsyncT' and 'WAsyncT' differ
162+-- in how they traverse streams in 'Semigroup' or 'Monad' compositions.
171163
172164-- $zipping
173165--
174−-- 'ZipStreamM' and 'ZipParallelM', provide 'Applicative' instances for zipping the
166+-- 'ZipSerialM' and 'ZipAsyncM', provide 'Applicative' instances for zipping the
175167-- corresponding elements of two streams together. Note that these types are
176168-- not monads.
177169
@@ -189,11 +181,11 @@ import Data.Semigroup (Semigroup(..))
189181-- one stream type to another. It is not used directly, instead the type
190182-- combinators provided below are used for conversions.
191183--
192−-- To adapt from one monomorphic type (e.g. 'parAheadT') to another monomorphic
193−-- type (e.g. 'StreamT') use the 'adapt' combinator. To give a polymorphic code
184+-- To adapt from one monomorphic type (e.g. 'AsyncT') to another monomorphic
185+-- type (e.g. 'SerialT') use the 'adapt' combinator. To give a polymorphic code
194186-- a specific interpretation or to adapt a specific type to a polymorphic type
195−-- use the type specific combinators e.g. 'asParAhead' or 'asCostream'. You
196−-- cannot adapt polymorphic code to polymorphic code, as it would not know
187+-- use the type specific combinators e.g. 'asyncly' or 'wSerially'. You
188+-- cannot adapt polymorphic code to polymorphic code, as the compiler would not know
197189-- which specific type you are converting from or to. If you see a an
198190-- @ambiguous type variable@ error then most likely you are using 'adapt'
199191-- unnecessarily on polymorphic code.
@@ -202,5 +194,5 @@ import Data.Semigroup (Semigroup(..))
202194-- $foldutils
203195--
204196-- These are variants of standard 'Foldable' fold functions that use a
205−-- polymorphic stream sum operation (e.g. 'parAhead' or 'cosplice') to fold a
197+-- polymorphic stream sum operation (e.g. 'async' or 'wSerial') to fold a
206198-- container of streams.
src/Streamly/Core.hs+40−46
@@ -20,8 +20,7 @@
2020--
2121module Streamly.Core
2222 (
23− MonadParallel
24− , MonadAsync -- deprecated
23+ MonadAsync
2524
2625 -- * Streams
2726 , Stream (..)
@@ -35,10 +34,10 @@ module Streamly.Core
3534 , nil
3635
3736 -- * Semigroup Style Composition
38− , splice
39− , cosplice
40− , parAhead
41− , coparAhead
37+ , serial
38+ , wSerial
39+ , async
40+ , wAsync
4241 , parallel
4342
4443 -- * Alternative
@@ -46,7 +45,7 @@ module Streamly.Core
4645
4746 -- * zip
4847 , zipWith
49− , zipParallelWith
48+ , zipAsyncWith
5049
5150 -- * Transformers
5251 , withLocal
@@ -234,8 +233,8 @@ repeat a = let x = cons a x in x
234233
235234-- | Concatenates two streams sequentially i.e. the first stream is
236235-- exhausted completely before yielding any element from the second stream.
237−splice :: Stream m a -> Stream m a -> Stream m a
238−splice m1 m2 = go m1
236+serial :: Stream m a -> Stream m a -> Stream m a
237+serial m1 m2 = go m1
239238 where
240239 go (Stream m) = Stream $ \_ stp sng yld ->
241240 let stop = (runStream m2) Nothing stp sng yld
@@ -244,7 +243,7 @@ splice m1 m2 = go m1
244243 in m Nothing stop single yield
245244
246245instance Semigroup (Stream m a) where
247− (<>) = splice
246+ (<>) = serial
248247
249248------------------------------------------------------------------------------
250249-- Monoid
@@ -258,11 +257,11 @@ instance Monoid (Stream m a) where
258257-- Interleave
259258------------------------------------------------------------------------------
260259
261−cosplice :: Stream m a -> Stream m a -> Stream m a
262−cosplice m1 m2 = Stream $ \_ stp sng yld -> do
260+wSerial :: Stream m a -> Stream m a -> Stream m a
261+wSerial m1 m2 = Stream $ \_ stp sng yld -> do
263262 let stop = (runStream m2) Nothing stp sng yld
264263 single a = yld a m2
265− yield a r = yld a (cosplice m2 r)
264+ yield a r = yld a (wSerial m2 r)
266265 (runStream m1) Nothing stop single yield
267266
268267------------------------------------------------------------------------------
@@ -271,15 +270,10 @@ cosplice m1 m2 = Stream $ \_ stp sng yld -> do
271270
272271-- | A monad that can perform concurrent or parallel IO operations. Streams
273272-- that can be composed concurrently require the underlying monad to be
274−-- 'MonadParallel'.
273+-- 'MonadAsync'.
275274--
276−-- @since 0.2.0
277−type MonadParallel m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
278−
279−-- |
280275-- @since 0.1.0
281−{-# DEPRECATED MonadAsync "Please use MonadParallel instead." #-}
282−type MonadAsync m = MonadParallel m
276+type MonadAsync m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
283277
284278-- Stolen from the async package. The perf improvement is modest, 2% on a
285279-- thread heavy benchmark (parallel composition using noop computations).
@@ -453,7 +447,7 @@ handleChildException sv e = do
453447 send sv (ChildStop tid (Just e))
454448
455449{-# NOINLINE pushWorker #-}
456−pushWorker :: MonadParallel m => SVar m a -> m ()
450+pushWorker :: MonadAsync m => SVar m a -> m ()
457451pushWorker sv = do
458452 liftIO $ atomicModifyIORefCAS_ (activeWorkers sv) $ \n -> n + 1
459453 doFork (runqueue sv) (handleChildException sv) >>= addThread sv
@@ -464,7 +458,7 @@ pushWorker sv = do
464458-- runningThreads. Alternatively, we can use a CreateThread event to avoid
465459-- using a CAS based modification.
466460{-# NOINLINE pushWorkerPar #-}
467−pushWorkerPar :: MonadParallel m => SVar m a -> Stream m a -> m ()
461+pushWorkerPar :: MonadAsync m => SVar m a -> Stream m a -> m ()
468462pushWorkerPar sv m =
469463 doFork (runOne sv m) (handleChildException sv) >>= modifyThread sv
470464
@@ -473,7 +467,7 @@ pushWorkerPar sv m =
473467-- block or make it go away entirely, depending on the number of workers and
474468-- the type of the queue.
475469{-# INLINE sendWorkerWait #-}
476−sendWorkerWait :: MonadParallel m => SVar m a -> m ()
470+sendWorkerWait :: MonadAsync m => SVar m a -> m ()
477471sendWorkerWait sv = do
478472 -- When there is no output seen we dispatch more workers to help out if
479473 -- there is work pending in the work queue. But we wait a little while
@@ -497,7 +491,7 @@ sendWorkerWait sv = do
497491
498492-- | Pull a stream from an SVar.
499493{-# NOINLINE fromStreamVar #-}
500−fromStreamVar :: MonadParallel m => SVar m a -> Stream m a
494+fromStreamVar :: MonadAsync m => SVar m a -> Stream m a
501495fromStreamVar sv = Stream $ \_ stp sng yld -> do
502496 let SVarStyle _ sched = svarStyle sv
503497 if sched == Par
@@ -607,7 +601,7 @@ getParSVar style = do
607601 in return sv
608602
609603-- | Create a new empty SVar.
610−newEmptySVar :: MonadParallel m => SVarStyle -> m (SVar m a)
604+newEmptySVar :: MonadAsync m => SVarStyle -> m (SVar m a)
611605newEmptySVar style = do
612606 liftIO $
613607 case style of
@@ -616,7 +610,7 @@ newEmptySVar style = do
616610 SVarStyle _ Par -> getParSVar style
617611
618612-- | Create a new SVar and enqueue one stream computation on it.
619−newStreamVar1 :: MonadParallel m => SVarStyle -> Stream m a -> m (SVar m a)
613+newStreamVar1 :: MonadAsync m => SVarStyle -> Stream m a -> m (SVar m a)
620614newStreamVar1 style m = do
621615 sv <- newEmptySVar style
622616 -- Note: We must have all the work on the queue before sending the
@@ -627,7 +621,7 @@ newStreamVar1 style m = do
627621 return sv
628622
629623-- | Create a new SVar and enqueue two stream computations on it.
630−newStreamVar2 :: MonadParallel m
624+newStreamVar2 :: MonadAsync m
631625 => SVarStyle -> Stream m a -> Stream m a -> m (SVar m a)
632626newStreamVar2 style m1 m2 = do
633627 -- Note: We must have all the work on the queue before sending the
@@ -649,7 +643,7 @@ newStreamVar2 style m1 m2 = do
649643
650644-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
651645-- be read back from the SVar using 'fromSVar'.
652−toStreamVar :: MonadParallel m => SVar m a -> Stream m a -> m ()
646+toStreamVar :: MonadAsync m => SVar m a -> Stream m a -> m ()
653647toStreamVar sv m = do
654648 liftIO $ (enqueue sv) m
655649 done <- allThreadsDone sv
@@ -678,7 +672,7 @@ toStreamVar sv m = do
678672--
679673-- TBD Note 2: We may want to run computations at the lower level of the
680674-- composition tree serially even when they are composed using a parallel
681−-- combinator. We can use 'splice' in place of 'parAhead' and 'cosplice' in
675+-- combinator. We can use 'splice' in place of 'async' and 'cosplice' in
682676-- place of 'coParAhead'. If we find that an SVar immediately above a computation
683677-- gets drained empty we can switch to parallelizing the computation. For that
684678-- we can use a state flag to fork the rest of the computation at any point of
@@ -714,16 +708,16 @@ toStreamVar sv m = do
714708-- Cases when we need to switch to a new SVar:
715709--
716710-- * (x `parallel` y) `parallel` (t `parallel` u) -- all of them get scheduled on the same SVar
717−-- * (x `parallel` y) `parallel` (t `parAhead` u) -- @t@ and @u@ get scheduled on a new child SVar
711+-- * (x `parallel` y) `parallel` (t `async` u) -- @t@ and @u@ get scheduled on a new child SVar
718712-- because of the scheduling policy change.
719−-- * if we 'adapt' a stream of type 'parAhead' to a stream of type
713+-- * if we 'adapt' a stream of type 'async' to a stream of type
720714-- 'Parallel', we create a new SVar at the transitioning bind.
721715-- * When the stream is switching from disjunctive composition to conjunctive
722716-- composition and vice-versa we create a new SVar to isolate the scheduling
723717-- of the two.
724718--
725719{-# INLINE joinStreamVar2 #-}
726−joinStreamVar2 :: MonadParallel m
720+joinStreamVar2 :: MonadAsync m
727721 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
728722joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
729723 case svr of
@@ -738,7 +732,7 @@ joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
738732 (runStream ma) svr stp sng yld
739733
740734{-# INLINE joinStreamVarPar #-}
741−joinStreamVarPar :: MonadParallel m
735+joinStreamVarPar :: MonadAsync m
742736 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
743737joinStreamVarPar style m1 m2 = Stream $ \svr stp sng yld ->
744738 case svr of
@@ -754,16 +748,16 @@ joinStreamVarPar style m1 m2 = Stream $ \svr stp sng yld ->
754748-- Semigroup and Monoid style compositions for parallel actions
755749------------------------------------------------------------------------------
756750
757−{-# INLINE parAhead #-}
758−parAhead :: MonadParallel m => Stream m a -> Stream m a -> Stream m a
759−parAhead = joinStreamVar2 (SVarStyle Disjunction LIFO)
751+{-# INLINE async #-}
752+async :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
753+async = joinStreamVar2 (SVarStyle Disjunction LIFO)
760754
761−{-# INLINE coparAhead #-}
762−coparAhead :: MonadParallel m => Stream m a -> Stream m a -> Stream m a
763−coparAhead = joinStreamVar2 (SVarStyle Disjunction FIFO)
755+{-# INLINE wAsync #-}
756+wAsync :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
757+wAsync = joinStreamVar2 (SVarStyle Disjunction FIFO)
764758
765759{-# INLINE parallel #-}
766−parallel :: MonadParallel m => Stream m a -> Stream m a -> Stream m a
760+parallel :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
767761parallel = joinStreamVarPar (SVarStyle Disjunction Par)
768762
769763-------------------------------------------------------------------------------
@@ -801,15 +795,15 @@ zipWith f m1 m2 = go m1 m2
801795 yield1 a ra = merge a ra
802796 (runStream mx) Nothing stp single1 yield1
803797
804−async :: MonadParallel m => Stream m a -> m (Stream m a)
805−async m = newStreamVar1 (SVarStyle Disjunction LIFO) m
798+mkAsync :: MonadAsync m => Stream m a -> m (Stream m a)
799+mkAsync m = newStreamVar1 (SVarStyle Disjunction LIFO) m
806800 >>= return . fromStreamVar
807801
808−zipParallelWith :: MonadParallel m
802+zipAsyncWith :: MonadAsync m
809803 => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
810−zipParallelWith f m1 m2 = Stream $ \_ stp sng yld -> do
811− ma <- async m1
812− mb <- async m2
804+zipAsyncWith f m1 m2 = Stream $ \_ stp sng yld -> do
805+ ma <- mkAsync m1
806+ mb <- mkAsync m2
813807 (runStream (zipWith f ma mb)) Nothing stp sng yld
814808
815809-------------------------------------------------------------------------------
src/Streamly/Prelude.hs+36−52
@@ -26,7 +26,7 @@
2626-- provided for convenience and for consistency with other pure APIs in the
2727-- @base@ package.
2828--
29−-- Deconstruction and folds accept a 'StreamT' type instead of a polymorphic
29+-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
3030-- type to ensure that streams always have a concrete monomorphic type by
3131-- default, reducing type errors. In case you want to use any other type of
3232-- stream you can use one of the type combinators provided in the "Streamly"
@@ -106,8 +106,8 @@ module Streamly.Prelude
106106 -- * Zipping
107107 , zipWith
108108 , zipWithM
109− , zipParallelWith
110− , zipParallelWithM
109+ , zipAsyncWith
110+ , zipAsyncWithM
111111
112112 -- * IO
113113 , fromHandle
@@ -118,8 +118,6 @@ module Streamly.Prelude
118118 , scan
119119 , foldl
120120 , foldlM
121− , zipAsyncWith
122− , zipAsyncWithM
123121 )
124122where
125123
@@ -260,7 +258,7 @@ fromHandle h = fromStream go
260258-- @
261259--
262260-- @since 0.1.0
263−foldr :: Monad m => (a -> b -> b) -> b -> StreamT m a -> m b
261+foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
264262foldr step acc m = go (toStream m)
265263 where
266264 go m1 =
@@ -279,7 +277,7 @@ foldr step acc m = go (toStream m)
279277--
280278-- @since 0.2.0
281279{-# INLINE foldrM #-}
282−foldrM :: Monad m => (a -> b -> m b) -> b -> StreamT m a -> m b
280+foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
283281foldrM step acc m = go (toStream m)
284282 where
285283 go m1 =
@@ -328,7 +326,7 @@ scanl' step begin m = scanx step begin id m
328326--
329327-- @since 0.2.0
330328{-# INLINE foldx #-}
331−foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> StreamT m a -> m b
329+foldx :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
332330foldx step begin done m = get $ go (toStream m) begin
333331 where
334332 {-# NOINLINE get #-}
@@ -351,21 +349,21 @@ foldx step begin done m = get $ go (toStream m) begin
351349-- |
352350-- @since 0.1.0
353351{-# DEPRECATED foldl "Please use foldx instead." #-}
354−foldl :: Monad m => (x -> a -> x) -> x -> (x -> b) -> StreamT m a -> m b
352+foldl :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
355353foldl = foldx
356354
357355-- | Strict left associative fold.
358356--
359357-- @since 0.2.0
360358{-# INLINE foldl' #-}
361−foldl' :: Monad m => (b -> a -> b) -> b -> StreamT m a -> m b
359+foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
362360foldl' step begin m = foldx step begin id m
363361
364362-- XXX replace the recursive "go" with explicit continuations.
365363-- | Like 'foldx', but with a monadic step function.
366364--
367365-- @since 0.2.0
368−foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> StreamT m a -> m b
366+foldxM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
369367foldxM step begin done m = go begin (toStream m)
370368 where
371369 go !acc m1 =
@@ -377,13 +375,13 @@ foldxM step begin done m = go begin (toStream m)
377375-- |
378376-- @since 0.1.0
379377{-# DEPRECATED foldlM "Please use foldxM instead." #-}
380−foldlM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> StreamT m a -> m b
378+foldlM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
381379foldlM = foldxM
382380
383381-- | Like 'foldl'' but with a monadic step function.
384382--
385383-- @since 0.2.0
386−foldlM' :: Monad m => (b -> a -> m b) -> b -> StreamT m a -> m b
384+foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
387385foldlM' step begin m = foldxM step (return begin) return m
388386
389387-- | Decompose a stream into its head and tail. If the stream is empty, returns
@@ -391,7 +389,7 @@ foldlM' step begin m = foldxM step (return begin) return m
391389-- the head of the stream and 'ma' its tail.
392390--
393391-- @since 0.1.0
394−uncons :: (IsStream t, Monad m) => StreamT m a -> m (Maybe (a, t m a))
392+uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
395393uncons m =
396394 let stop = return Nothing
397395 single a = return (Just (a, nil))
@@ -401,7 +399,7 @@ uncons m =
401399-- | Write a stream of Strings to an IO Handle.
402400--
403401-- @since 0.1.0
404−toHandle :: MonadIO m => IO.Handle -> StreamT m String -> m ()
402+toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
405403toHandle h m = go (toStream m)
406404 where
407405 go m1 =
@@ -418,7 +416,7 @@ toHandle h m = go (toStream m)
418416--
419417-- @since 0.1.0
420418{-# INLINABLE toList #-}
421−toList :: Monad m => StreamT m a -> m [a]
419+toList :: Monad m => SerialT m a -> m [a]
422420toList = foldrM (\a xs -> return (a : xs)) []
423421
424422-- | Take first 'n' elements from the stream and discard the rest.
@@ -492,7 +490,7 @@ dropWhile p m = fromStream $ go (toStream m)
492490-- | Determine whether all elements of a stream satisfy a predicate.
493491--
494492-- @since 0.1.0
495−all :: Monad m => (a -> Bool) -> StreamT m a -> m Bool
493+all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
496494all p m = go (toStream m)
497495 where
498496 go m1 =
@@ -505,7 +503,7 @@ all p m = go (toStream m)
505503-- | Determine whether any of the elements of a stream satisfy a predicate.
506504--
507505-- @since 0.1.0
508−any :: Monad m => (a -> Bool) -> StreamT m a -> m Bool
506+any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
509507any p m = go (toStream m)
510508 where
511509 go m1 =
@@ -518,19 +516,19 @@ any p m = go (toStream m)
518516-- | Determine the sum of all elements of a stream of numbers
519517--
520518-- @since 0.1.0
521−sum :: (Monad m, Num a) => StreamT m a -> m a
519+sum :: (Monad m, Num a) => SerialT m a -> m a
522520sum = foldl (+) 0 id
523521
524522-- | Determine the product of all elements of a stream of numbers
525523--
526524-- @since 0.1.1
527−product :: (Monad m, Num a) => StreamT m a -> m a
525+product :: (Monad m, Num a) => SerialT m a -> m a
528526product = foldl (*) 1 id
529527
530528-- | Extract the first element of the stream, if any.
531529--
532530-- @since 0.1.0
533−head :: Monad m => StreamT m a -> m (Maybe a)
531+head :: Monad m => SerialT m a -> m (Maybe a)
534532head m =
535533 let stop = return Nothing
536534 single a = return (Just a)
@@ -540,7 +538,7 @@ head m =
540538-- | Extract all but the first element of the stream, if any.
541539--
542540-- @since 0.1.1
543−tail :: (IsStream t, Monad m) => StreamT m a -> m (Maybe (t m a))
541+tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
544542tail m =
545543 let stop = return Nothing
546544 single _ = return $ Just nil
@@ -551,13 +549,13 @@ tail m =
551549--
552550-- @since 0.1.1
553551{-# INLINE last #-}
554−last :: Monad m => StreamT m a -> m (Maybe a)
552+last :: Monad m => SerialT m a -> m (Maybe a)
555553last = foldl (\_ y -> Just y) Nothing id
556554
557555-- | Determine whether the stream is empty.
558556--
559557-- @since 0.1.1
560−null :: Monad m => StreamT m a -> m Bool
558+null :: Monad m => SerialT m a -> m Bool
561559null m =
562560 let stop = return True
563561 single _ = return False
@@ -567,7 +565,7 @@ null m =
567565-- | Determine whether an element is present in the stream.
568566--
569567-- @since 0.1.0
570−elem :: (Monad m, Eq a) => a -> StreamT m a -> m Bool
568+elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
571569elem e m = go (toStream m)
572570 where
573571 go m1 =
@@ -579,7 +577,7 @@ elem e m = go (toStream m)
579577-- | Determine whether an element is not present in the stream.
580578--
581579-- @since 0.1.0
582−notElem :: (Monad m, Eq a) => a -> StreamT m a -> m Bool
580+notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
583581notElem e m = go (toStream m)
584582 where
585583 go m1 =
@@ -591,7 +589,7 @@ notElem e m = go (toStream m)
591589-- | Determine the length of the stream.
592590--
593591-- @since 0.1.0
594−length :: Monad m => StreamT m a -> m Int
592+length :: Monad m => SerialT m a -> m Int
595593length = foldl (\n _ -> n + 1) 0 id
596594
597595-- | Returns the elements of the stream in reverse order.
@@ -612,7 +610,7 @@ reverse m = fromStream $ go S.nil (toStream m)
612610-- | Determine the minimum element in a stream.
613611--
614612-- @since 0.1.0
615−minimum :: (Monad m, Ord a) => StreamT m a -> m (Maybe a)
613+minimum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
616614minimum m = go Nothing (toStream m)
617615 where
618616 go res m1 =
@@ -629,7 +627,7 @@ minimum m = go Nothing (toStream m)
629627-- | Determine the maximum element in a stream.
630628--
631629-- @since 0.1.0
632−maximum :: (Monad m, Ord a) => StreamT m a -> m (Maybe a)
630+maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
633631maximum m = go Nothing (toStream m)
634632 where
635633 go res m1 =
@@ -665,7 +663,7 @@ mapM f m = fromStream $ go (toStream m)
665663-- output of the action.
666664--
667665-- @since 0.1.0
668−mapM_ :: Monad m => (a -> m b) -> StreamT m a -> m ()
666+mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
669667mapM_ f m = go (toStream m)
670668 where
671669 go m1 =
@@ -719,33 +717,19 @@ zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
719717-- | Zip two streams concurrently (i.e. both the elements being zipped are
720718-- generated concurrently) using a pure zipping function.
721719--
722−-- @since 0.2.0
723−zipParallelWith :: (IsStream t, MonadParallel m)
724− => (a -> b -> c) -> t m a -> t m b -> t m c
725−zipParallelWith f m1 m2 =
726− fromStream $ S.zipParallelWith f (toStream m1) (toStream m2)
727−
728−-- |
729720-- @since 0.1.0
730−{-# DEPRECATED zipAsyncWith "Please use zipParallelWith instead." #-}
731−zipAsyncWith :: (IsStream t, MonadParallel m)
721+zipAsyncWith :: (IsStream t, MonadAsync m)
732722 => (a -> b -> c) -> t m a -> t m b -> t m c
733−zipAsyncWith = zipParallelWith
723+zipAsyncWith f m1 m2 =
724+ fromStream $ S.zipAsyncWith f (toStream m1) (toStream m2)
734725
735726-- | Zip two streams asyncly (i.e. both the elements being zipped are generated
736727-- concurrently) using a monadic zipping function.
737728--
738−-- @since 0.2.0
739−zipParallelWithM :: (IsStream t, MonadParallel m)
740− => (a -> b -> t m c) -> t m a -> t m b -> t m c
741−zipParallelWithM f m1 m2 = fromStream $ Stream $ \_ stp sng yld -> do
742− ma <- async m1
743− mb <- async m2
744− (S.runStream (toStream (zipWithM f ma mb))) Nothing stp sng yld
745−
746−-- |
747729-- @since 0.1.0
748−{-# DEPRECATED zipAsyncWithM "Please use zipParallelWithM instead." #-}
749−zipAsyncWithM :: (IsStream t, MonadParallel m)
730+zipAsyncWithM :: (IsStream t, MonadAsync m)
750731 => (a -> b -> t m c) -> t m a -> t m b -> t m c
751−zipAsyncWithM = zipParallelWithM
732+zipAsyncWithM f m1 m2 = fromStream $ Stream $ \_ stp sng yld -> do
733+ ma <- mkAsync m1
734+ mb <- mkAsync m2
735+ (S.runStream (toStream (zipWithM f ma mb))) Nothing stp sng yld
src/Streamly/Streams.hs+260−278
@@ -22,8 +22,7 @@ module Streamly.Streams
2222 (
2323 IsStream (..)
2424 , Streaming -- deprecated
25− , MonadParallel
26− , S.MonadAsync -- deprecated
25+ , S.MonadAsync
2726
2827 -- * SVars
2928 , SVarSched (..)
@@ -49,51 +48,48 @@ module Streamly.Streams
4948 , toSVar
5049
5150 -- * Transformation
52− , async
51+ , mkAsync
5352
5453 -- * Merging Streams
55− , splice
56− , cosplice
57− , parAhead
58− , coparAhead
54+ , serial
55+ , wSerial
56+ , async
57+ , wAsync
5958 , parallel
6059 , (<=>) --deprecated
6160 , (<|) --deprecated
6261
6362 -- * IO Streams
64− , Stream
65− , Costream
66− , ParAhead
67− , CoparAhead
63+ , Serial
64+ , WSerial
65+ , Async
66+ , WAsync
6867 , Parallel
69− , ZipStream
70− , ZipParallel
68+ , ZipSerial
69+ , ZipAsync
7170
7271 -- * Stream Transformers
73− , StreamT
74− , CostreamT
72+ , SerialT
73+ , StreamT -- deprecated
74+ , WSerialT
7575 , InterleavedT -- deprecated
76− , ParAheadT
77− , AsyncT -- deprecated
78− , CoparAheadT
76+ , AsyncT
77+ , WAsyncT
7978 , ParallelT
80− , ZipStreamM
81− , ZipParallelM
82− , ZipAsync -- deprecated
79+ , ZipStream -- deprecated
80+ , ZipSerialM
81+ , ZipAsyncM
8382
8483 -- * Type Adapters
85− , asStream
8684 , serially -- deprecated
87− , asCostream
85+ , wSerially
8886 , interleaving -- deprecated
89− , asParAhead
90− , asyncly -- deprecated
91− , asCoparAhead
92− , asParallel
93− , parallely -- deprecated
94− , asZipStream
87+ , asyncly
88+ , wAsyncly
89+ , parallely
90+ , zipSerially
9591 , zipping -- deprecated
96− , asZipParallel
92+ , zipAsyncly
9793 , zippingAsync -- deprecated
9894 , adapt
9995
@@ -121,7 +117,7 @@ import Control.Monad.Reader.Class (MonadReader(..))
121117import Control.Monad.State.Class (MonadState(..))
122118import Control.Monad.Trans.Class (MonadTrans (lift))
123119import Data.Semigroup (Semigroup(..))
124−import Streamly.Core ( MonadParallel
120+import Streamly.Core ( MonadAsync
125121 , SVar, SVarStyle(..)
126122 , SVarTag(..), SVarSched(..))
127123import qualified Streamly.Core as S
@@ -238,7 +234,7 @@ fromCallback :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
238234fromCallback k = fromStream $ S.Stream $ \_ _ sng _ -> k sng
239235
240236-- | Read an SVar to get a stream.
241−fromSVar :: (MonadParallel m, IsStream t) => SVar m a -> t m a
237+fromSVar :: (MonadAsync m, IsStream t) => SVar m a -> t m a
242238fromSVar sv = fromStream $ S.fromStreamVar sv
243239
244240------------------------------------------------------------------------------
@@ -261,11 +257,11 @@ streamFold svr step single blank m =
261257 in (S.runStream (toStream m)) svr blank single yield
262258
263259-- | Run a streaming composition, discard the results. By default it interprets
264−-- the stream as 'StreamT', to run other types of streams use the type adapting
265−-- combinators for example @runStream . 'asParAhead'@.
260+-- the stream as 'SerialT', to run other types of streams use the type adapting
261+-- combinators for example @runStream . 'asyncly'@.
266262--
267263-- @since 0.2.0
268−runStream :: Monad m => StreamT m a -> m ()
264+runStream :: Monad m => SerialT m a -> m ()
269265runStream m = go (toStream m)
270266 where
271267 go m1 =
@@ -283,7 +279,7 @@ runStreaming = runStream . adapt
283279
284280-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
285281-- be read back from the SVar using 'fromSVar'.
286−toSVar :: (IsStream t, MonadParallel m) => SVar m a -> t m a -> m ()
282+toSVar :: (IsStream t, MonadAsync m) => SVar m a -> t m a -> m ()
287283toSVar sv m = S.toStreamVar sv (toStream m)
288284
289285------------------------------------------------------------------------------
@@ -297,9 +293,9 @@ toSVar sv m = S.toStreamVar sv (toStream m)
297293-- not drained fully we may have a thread blocked forever and once exhausted it
298294-- will always return 'empty'.
299295--
300−-- @since 0.1.0
301−async :: (IsStream t, MonadParallel m) => t m a -> m (t m a)
302−async m = do
296+-- @since 0.2.0
297+mkAsync :: (IsStream t, MonadAsync m) => t m a -> m (t m a)
298+mkAsync m = do
303299 sv <- S.newStreamVar1 (SVarStyle Disjunction LIFO) (toStream m)
304300 return $ fromSVar sv
305301
@@ -310,7 +306,7 @@ async m = do
310306-- XXX use template haskell instead and include Monoid and IsStream instances
311307-- as well.
312308
313−#define MONADPARALLEL , MonadParallel m
309+#define MONADPARALLEL , MonadAsync m
314310
315311#define MONAD_APPLICATIVE_INSTANCE(STREAM,CONSTRAINT) \
316312instance (Monad m CONSTRAINT) => Applicative (STREAM m) where { \
@@ -344,25 +340,26 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
344340 state k = lift (state k) }
345341
346342------------------------------------------------------------------------------
347−-- StreamT
343+-- SerialT
348344------------------------------------------------------------------------------
349345
350−-- | The 'Semigroup' instance of 'StreamT' appends two streams sequentially,
351−-- yielding all elements from the first stream, and then all elements from the
352−-- second stream.
346+-- | Deep serial composition or serial composition with depth first traversal.
347+-- The 'Semigroup' instance of 'SerialT' appends two streams serially in a
348+-- depth first manner, yielding all elements from the first stream, and then
349+-- all elements from the second stream.
353350--
354351-- @
355−-- main = ('toList' . 'asStream' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
352+-- main = ('toList' . 'serially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
356353-- @
357354-- @
358355-- [1,2,3,4]
359356-- @
360357--
361358-- The 'Monad' instance runs the /monadic continuation/ for each
362−-- element of the stream, asStream.
359+-- element of the stream, serially.
363360--
364361-- @
365−-- main = 'runStream' . 'asStream' $ do
362+-- main = 'runStream' . 'serially' $ do
366363-- x <- return 1 \<\> return 2
367364-- liftIO $ print x
368365-- @
@@ -371,10 +368,10 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
371368-- 2
372369-- @
373370--
374−-- 'StreamT' nests streams serially in a depth first manner.
371+-- 'SerialT' nests streams serially in a depth first manner.
375372--
376373-- @
377−-- main = 'runStream' . 'asStream' $ do
374+-- main = 'runStream' . 'serially' $ do
378375-- x <- return 1 \<\> return 2
379376-- y <- return 3 \<\> return 4
380377-- liftIO $ print (x, y)
@@ -386,45 +383,51 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
386383-- (2,4)
387384-- @
388385--
389−-- This behavior of 'StreamT' is exactly like a list transformer. We call the
386+-- This behavior of 'SerialT' is exactly like a list transformer. We call the
390387-- monadic code being run for each element of the stream a monadic
391388-- continuation. In imperative paradigm we can think of this composition as
392389-- nested @for@ loops and the monadic continuation is the body of the loop. The
393390-- loop iterates for all elements of the stream.
394391--
395−-- The 'asStream' combinator can be omitted as the default stream type is
396−-- 'StreamT'.
397−-- Note that serial composition can be used to combine an infinite number of
398−-- streams as it explores only one stream at a time.
392+-- The 'serially' combinator can be omitted as the default stream type is
393+-- 'SerialT'.
394+-- Note that serial composition with depth first traversal can be used to
395+-- combine an infinite number of streams as it explores only one stream at a
396+-- time.
399397--
400−-- @since 0.1.0
401−newtype StreamT m a = StreamT {getStreamT :: S.Stream m a}
398+-- @since 0.2.0
399+newtype SerialT m a = SerialT {getSerialT :: S.Stream m a}
402400 deriving (Semigroup, Monoid, Functor, MonadTrans)
403401
404−instance IsStream StreamT where
405− toStream = getStreamT
406− fromStream = StreamT
402+-- |
403+-- @since 0.1.0
404+{-# DEPRECATED StreamT "Please use 'SerialT' instead." #-}
405+type StreamT = SerialT
406+
407+instance IsStream SerialT where
408+ toStream = getSerialT
409+ fromStream = SerialT
407410
408411------------------------------------------------------------------------------
409412-- Semigroup
410413------------------------------------------------------------------------------
411414
412−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'StreamT'.
415+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'SerialT'.
413416-- Appends two streams sequentially, yielding all elements from the first
414417-- stream, and then all elements from the second stream.
415418--
416419-- @since 0.2.0
417−{-# INLINE splice #-}
418−splice :: IsStream t => t m a -> t m a -> t m a
419−splice m1 m2 = fromStream $ S.splice (toStream m1) (toStream m2)
420+{-# INLINE serial #-}
421+serial :: IsStream t => t m a -> t m a -> t m a
422+serial m1 m2 = fromStream $ S.serial (toStream m1) (toStream m2)
420423
421424------------------------------------------------------------------------------
422425-- Monad
423426------------------------------------------------------------------------------
424427
425−instance Monad m => Monad (StreamT m) where
428+instance Monad m => Monad (SerialT m) where
426429 return = pure
427− (StreamT (S.Stream m)) >>= f = StreamT $ S.Stream $ \_ stp sng yld ->
430+ (SerialT (S.Stream m)) >>= f = SerialT $ S.Stream $ \_ stp sng yld ->
428431 let run x = (S.runStream x) Nothing stp sng yld
429432 single a = run $ toStream (f a)
430433 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
@@ -434,29 +437,31 @@ instance Monad m => Monad (StreamT m) where
434437-- Other instances
435438------------------------------------------------------------------------------
436439
437−MONAD_APPLICATIVE_INSTANCE(StreamT,)
438−MONAD_COMMON_INSTANCES(StreamT,)
440+MONAD_APPLICATIVE_INSTANCE(SerialT,)
441+MONAD_COMMON_INSTANCES(SerialT,)
439442
440443------------------------------------------------------------------------------
441−-- CostreamT
444+-- WSerialT
442445------------------------------------------------------------------------------
443446
444−-- | The 'Semigroup' instance of 'CostreamT' interleaves two streams,
445−-- yielding one element from each stream alternately.
447+-- | Wide serial composition or serial composition with a breadth first
448+-- traversal. The 'Semigroup' instance of 'WSerialT' traverses
449+-- the two streams in a breadth first manner. In other words, it interleaves
450+-- two streams, yielding one element from each stream alternately.
446451--
447452-- @
448−-- main = ('toList' . 'asCostream' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
453+-- main = ('toList' . 'wSerially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
449454-- @
450455-- @
451456-- [1,3,2,4]
452457-- @
453458--
454−-- Similarly, the 'Monad' instance fairly interleaves the iterations of the
459+-- Similarly, the 'Monad' instance interleaves the iterations of the
455460-- inner and the outer loop, nesting loops in a breadth first manner.
456461--
457462--
458463-- @
459−-- main = 'runStream' . 'asCostream' $ do
464+-- main = 'runStream' . 'wSerially' $ do
460465-- x <- return 1 \<\> return 2
461466-- y <- return 3 \<\> return 4
462467-- liftIO $ print (x, y)
@@ -468,52 +473,53 @@ MONAD_COMMON_INSTANCES(StreamT,)
468473-- (2,4)
469474-- @
470475--
471−-- Note that a 'Costream' composition can only combine a finite number of
472−-- streams as it needs to retain state for each unfinished stream.
476+-- Note that a serial composition with breadth first traversal can only combine
477+-- a finite number of streams as it needs to retain state for each unfinished
478+-- stream.
473479--
474480-- @since 0.2.0
475−newtype CostreamT m a = CostreamT {getCostreamT :: S.Stream m a}
481+newtype WSerialT m a = WSerialT {getWSerialT :: S.Stream m a}
476482 deriving (Functor, MonadTrans)
477483
478484-- |
479485-- @since 0.1.0
480−{-# DEPRECATED InterleavedT "Please use 'CostreamT' instead." #-}
481−type InterleavedT = CostreamT
486+{-# DEPRECATED InterleavedT "Please use 'WSerialT' instead." #-}
487+type InterleavedT = WSerialT
482488
483−instance IsStream CostreamT where
484− toStream = getCostreamT
485− fromStream = CostreamT
489+instance IsStream WSerialT where
490+ toStream = getWSerialT
491+ fromStream = WSerialT
486492
487493------------------------------------------------------------------------------
488494-- Semigroup
489495------------------------------------------------------------------------------
490496
491−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'CostreamT'.
497+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
492498-- Interleaves two streams, yielding one element from each stream alternately.
493499--
494500-- @since 0.2.0
495−{-# INLINE cosplice #-}
496−cosplice :: IsStream t => t m a -> t m a -> t m a
497−cosplice m1 m2 = fromStream $ S.cosplice (toStream m1) (toStream m2)
501+{-# INLINE wSerial #-}
502+wSerial :: IsStream t => t m a -> t m a -> t m a
503+wSerial m1 m2 = fromStream $ S.wSerial (toStream m1) (toStream m2)
498504
499−instance Semigroup (CostreamT m a) where
500− (<>) = cosplice
505+instance Semigroup (WSerialT m a) where
506+ (<>) = wSerial
501507
502508infixr 5 <=>
503509
504−-- | Same as 'cosplice'.
510+-- | Same as 'wSerial'.
505511--
506512-- @since 0.1.0
507−{-# DEPRECATED (<=>) "Please use 'cosplice' instead." #-}
513+{-# DEPRECATED (<=>) "Please use 'wSerial' instead." #-}
508514{-# INLINE (<=>) #-}
509515(<=>) :: IsStream t => t m a -> t m a -> t m a
510−(<=>) = cosplice
516+(<=>) = wSerial
511517
512518------------------------------------------------------------------------------
513519-- Monoid
514520------------------------------------------------------------------------------
515521
516−instance Monoid (CostreamT m a) where
522+instance Monoid (WSerialT m a) where
517523 mempty = nil
518524 mappend = (<>)
519525
@@ -521,9 +527,9 @@ instance Monoid (CostreamT m a) where
521527-- Monad
522528------------------------------------------------------------------------------
523529
524−instance Monad m => Monad (CostreamT m) where
530+instance Monad m => Monad (WSerialT m) where
525531 return = pure
526− (CostreamT (S.Stream m)) >>= f = CostreamT $ S.Stream $ \_ stp sng yld ->
532+ (WSerialT (S.Stream m)) >>= f = WSerialT $ S.Stream $ \_ stp sng yld ->
527533 let run x = (S.runStream x) Nothing stp sng yld
528534 single a = run $ toStream (f a)
529535 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
@@ -533,21 +539,21 @@ instance Monad m => Monad (CostreamT m) where
533539-- Other instances
534540------------------------------------------------------------------------------
535541
536−MONAD_APPLICATIVE_INSTANCE(CostreamT,)
537−MONAD_COMMON_INSTANCES(CostreamT,)
542+MONAD_APPLICATIVE_INSTANCE(WSerialT,)
543+MONAD_COMMON_INSTANCES(WSerialT,)
538544
539545------------------------------------------------------------------------------
540−-- ParAheadT
546+-- AsyncT
541547------------------------------------------------------------------------------
542548
543−-- | Adaptive ahead parallel, in a left to right 'Semigroup' composition it tries to
544−-- yield elements from the left stream as long as it can, but it can run the
545−-- right stream in parallel if it needs to, based on demand. The right stream
546−-- can be run if the left stream blocks on IO or cannot produce elements fast
547−-- enough for the consumer.
549+-- | Deep async composition or async composition with depth first traversal. In
550+-- a left to right 'Semigroup' composition it tries to yield elements from the
551+-- left stream as long as it can, but it can run the right stream in parallel
552+-- if it needs to, based on demand. The right stream can be run if the left
553+-- stream blocks on IO or cannot produce elements fast enough for the consumer.
548554--
549555-- @
550−-- main = ('toList' . 'asParAhead' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
556+-- main = ('toList' . 'asyncly' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
551557-- @
552558-- @
553559-- [1,2,3,4]
@@ -560,7 +566,7 @@ MONAD_COMMON_INSTANCES(CostreamT,)
560566-- different streams in the resulting stream can vary depending on scheduling
561567-- and generation delays.
562568--
563−-- Similarly, the monad instance of 'CoparAheadT' /may/ run each iteration
569+-- Similarly, the monad instance of 'AsyncT' /may/ run each iteration
564570-- concurrently based on demand. More concurrent iterations are started only
565571-- if the previous iterations are not able to produce enough output for the
566572-- consumer.
@@ -569,7 +575,7 @@ MONAD_COMMON_INSTANCES(CostreamT,)
569575-- import "Streamly"
570576-- import Control.Concurrent
571577--
572−-- main = 'runStream' . 'asParAhead' $ do
578+-- main = 'runStream' . 'asyncly' $ do
573579-- n <- return 3 \<\> return 2 \<\> return 1
574580-- liftIO $ do
575581-- threadDelay (n * 1000000)
@@ -583,51 +589,47 @@ MONAD_COMMON_INSTANCES(CostreamT,)
583589--
584590-- All iterations may run in the same thread if they do not block.
585591--
586−-- Note that this composition can be used to combine infinite number of streams
587−-- as it explores only a bounded number of streams at a time.
592+-- Note that async composition with depth first traversal can be used to
593+-- combine infinite number of streams as it explores only a bounded number of
594+-- streams at a time.
588595--
589−-- @since 0.2.0
590−newtype ParAheadT m a = ParAheadT {getParAheadT :: S.Stream m a}
591− deriving (Functor, MonadTrans)
592−
593−-- |
594596-- @since 0.1.0
595−{-# DEPRECATED AsyncT "Please use 'ParAheadT' instead." #-}
596−type AsyncT = ParAheadT
597+newtype AsyncT m a = AsyncT {getAsyncT :: S.Stream m a}
598+ deriving (Functor, MonadTrans)
597599
598−instance IsStream ParAheadT where
599− toStream = getParAheadT
600− fromStream = ParAheadT
600+instance IsStream AsyncT where
601+ toStream = getAsyncT
602+ fromStream = AsyncT
601603
602604------------------------------------------------------------------------------
603605-- Semigroup
604606------------------------------------------------------------------------------
605607
606−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'ParAheadT'.
608+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AsyncT'.
607609-- Merges two streams possibly concurrently, preferring the
608610-- elements from the left one when available.
609611--
610612-- @since 0.2.0
611−{-# INLINE parAhead #-}
612−parAhead :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
613−parAhead m1 m2 = fromStream $ S.parAhead (toStream m1) (toStream m2)
613+{-# INLINE async #-}
614+async :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
615+async m1 m2 = fromStream $ S.async (toStream m1) (toStream m2)
614616
615−instance MonadParallel m => Semigroup (ParAheadT m a) where
616− (<>) = parAhead
617+instance MonadAsync m => Semigroup (AsyncT m a) where
618+ (<>) = async
617619
618−-- | Same as 'parAhead'.
620+-- | Same as 'async'.
619621--
620622-- @since 0.1.0
621−{-# DEPRECATED (<|) "Please use 'parAhead' instead." #-}
623+{-# DEPRECATED (<|) "Please use 'async' instead." #-}
622624{-# INLINE (<|) #-}
623−(<|) :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
624−(<|) = parAhead
625+(<|) :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
626+(<|) = async
625627
626628------------------------------------------------------------------------------
627629-- Monoid
628630------------------------------------------------------------------------------
629631
630−instance MonadParallel m => Monoid (ParAheadT m a) where
632+instance MonadAsync m => Monoid (AsyncT m a) where
631633 mempty = nil
632634 mappend = (<>)
633635
@@ -650,28 +652,28 @@ parbind par m f = go m
650652 yield a r = run $ f a `par` go r
651653 in g Nothing stp single yield
652654
653−instance MonadParallel m => Monad (ParAheadT m) where
655+instance MonadAsync m => Monad (AsyncT m) where
654656 return = pure
655− (ParAheadT m) >>= f = ParAheadT $ parbind S.parAhead m (getParAheadT . f)
657+ (AsyncT m) >>= f = AsyncT $ parbind S.async m (getAsyncT . f)
656658
657659------------------------------------------------------------------------------
658660-- Other instances
659661------------------------------------------------------------------------------
660662
661−MONAD_APPLICATIVE_INSTANCE(ParAheadT,MONADPARALLEL)
662−MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
663+MONAD_APPLICATIVE_INSTANCE(AsyncT,MONADPARALLEL)
664+MONAD_COMMON_INSTANCES(AsyncT, MONADPARALLEL)
663665
664666------------------------------------------------------------------------------
665−-- CoparAheadT
667+-- WAsyncT
666668------------------------------------------------------------------------------
667669
668−-- | Round robin concurrent composition.
669−--
670−-- The Semigroup instance of 'CoparAheadT' concurrently /merges/ streams in a
671−-- round robin fashion, yielding elements from both streams alternately.
670+-- | Wide async composition or async composition with breadth first traversal.
671+-- The Semigroup instance of 'WAsyncT' concurrently /traverses/ the composed
672+-- streams using a depth first travesal or in a round robin fashion, yielding
673+-- elements from both streams alternately.
672674--
673675-- @
674−-- main = ('toList' . 'asCoparAhead' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
676+-- main = ('toList' . 'wAsyncly' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
675677-- @
676678-- @
677679-- [1,3,2,4]
@@ -684,14 +686,14 @@ MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
684686-- different streams in the resulting stream can vary depending on scheduling
685687-- and generation delays.
686688--
687−-- Similarly, the 'Monad' instance of 'CoparAheadT' runs /all/ iterations fairly
689+-- Similarly, the 'Monad' instance of 'WAsyncT' runs /all/ iterations fairly
688690-- concurrently using a round robin scheduling.
689691--
690692-- @
691693-- import "Streamly"
692694-- import Control.Concurrent
693695--
694−-- main = 'runStream' . 'asCoparAhead' $ do
696+-- main = 'runStream' . 'wAsyncly' $ do
695697-- n <- return 3 \<\> return 2 \<\> return 1
696698-- liftIO $ do
697699-- threadDelay (n * 1000000)
@@ -703,40 +705,41 @@ MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
703705-- ThreadId 38: Delay 3
704706-- @
705707--
706−-- Unlike 'ParAheadT' all iterations are guaranteed to run fairly
708+-- Unlike 'AsyncT' all iterations are guaranteed to run fairly
707709-- concurrently, unconditionally.
708710--
709−-- Note that round robin composition can only combine a finite number of
710−-- streams as it needs to retain state for each unfinished stream.
711+-- Note that async composition with breadth first traversal can only combine a
712+-- finite number of streams as it needs to retain state for each unfinished
713+-- stream.
711714--
712−-- @since 0.1.0
713−newtype CoparAheadT m a = CoparAheadT {getCoparAheadT :: S.Stream m a}
715+-- @since 0.2.0
716+newtype WAsyncT m a = WAsyncT {getWAsyncT :: S.Stream m a}
714717 deriving (Functor, MonadTrans)
715718
716−instance IsStream CoparAheadT where
717− toStream = getCoparAheadT
718− fromStream = CoparAheadT
719+instance IsStream WAsyncT where
720+ toStream = getWAsyncT
721+ fromStream = WAsyncT
719722
720723------------------------------------------------------------------------------
721724-- Semigroup
722725------------------------------------------------------------------------------
723726
724−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'CoparAheadT'.
727+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WAsyncT'.
725728-- Merges two streams concurrently choosing elements from both fairly.
726729--
727730-- @since 0.2.0
728−{-# INLINE coparAhead #-}
729−coparAhead :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
730−coparAhead m1 m2 = fromStream $ S.coparAhead (toStream m1) (toStream m2)
731+{-# INLINE wAsync #-}
732+wAsync :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
733+wAsync m1 m2 = fromStream $ S.wAsync (toStream m1) (toStream m2)
731734
732−instance MonadParallel m => Semigroup (CoparAheadT m a) where
733− (<>) = coparAhead
735+instance MonadAsync m => Semigroup (WAsyncT m a) where
736+ (<>) = wAsync
734737
735738------------------------------------------------------------------------------
736739-- Monoid
737740------------------------------------------------------------------------------
738741
739−instance MonadParallel m => Monoid (CoparAheadT m a) where
742+instance MonadAsync m => Monoid (WAsyncT m a) where
740743 mempty = nil
741744 mappend = (<>)
742745
@@ -744,23 +747,23 @@ instance MonadParallel m => Monoid (CoparAheadT m a) where
744747-- Monad
745748------------------------------------------------------------------------------
746749
747−instance MonadParallel m => Monad (CoparAheadT m) where
750+instance MonadAsync m => Monad (WAsyncT m) where
748751 return = pure
749− (CoparAheadT m) >>= f =
750− CoparAheadT $ parbind S.coparAhead m (getCoparAheadT . f)
752+ (WAsyncT m) >>= f =
753+ WAsyncT $ parbind S.wAsync m (getWAsyncT . f)
751754
752755------------------------------------------------------------------------------
753756-- Other instances
754757------------------------------------------------------------------------------
755758
756−MONAD_APPLICATIVE_INSTANCE(CoparAheadT,MONADPARALLEL)
757−MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
759+MONAD_APPLICATIVE_INSTANCE(WAsyncT,MONADPARALLEL)
760+MONAD_COMMON_INSTANCES(WAsyncT, MONADPARALLEL)
758761
759762------------------------------------------------------------------------------
760763-- ParallelT
761764------------------------------------------------------------------------------
762765
763−-- | Strictly parallel composition.
766+-- | Async composition with simultaneous traversal of all streams.
764767--
765768-- The Semigroup instance of 'ParallelT' concurrently /merges/ two streams,
766769-- running both strictly concurrently and yielding elements from both streams
@@ -768,7 +771,7 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
768771-- one is evaluated in its own thread and the results produced are presented in
769772-- the combined stream on a first come first serve basis.
770773--
771−-- 'ParAheadT' and 'CoparAheadT' are /concurrent lookahead streams/ each with a
774+-- 'AsyncT' and 'WAsyncT' are /concurrent lookahead streams/ each with a
772775-- specific type of consumption pattern (depth first or breadth first). Since
773776-- they are lookahead, they may introduce certain default latency in starting
774777-- more concurrent tasks for efficiency reasons or may put a default limitation
@@ -778,12 +781,12 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
778781-- the desired rate. However, 'ParallelT' uses a separate runtime thread to
779782-- evaluate each stream.
780783--
781−-- 'CoparAheadT' is similar to 'ParallelT', as both of them evaluate the
784+-- 'WAsyncT' is similar to 'ParallelT', as both of them evaluate the
782785-- constituent streams fairly in a round robin fashion.
783−-- However, the key difference is that 'CoparAheadT' is lazy or pull driven
786+-- However, the key difference is that 'WAsyncT' is lazy or pull driven
784787-- whereas 'ParallelT' is strict or push driven. 'ParallelT' immediately
785788-- starts concurrent evaluation of both the streams (in separate threads) and
786−-- later picks the results whereas 'CoparAheadT' may wait for a certain latency
789+-- later picks the results whereas 'WAsyncT' may wait for a certain latency
787790-- threshold before initiating concurrent evaluation of the next stream. The
788791-- concurrent scheduling of the next stream or the degree of concurrency is
789792-- driven by the feedback from the consumer. In case of 'ParallelT' each stream
@@ -801,18 +804,18 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
801804-- two tasks and want to start both strictly at the same time or if we have
802805-- timers in the parallel tasks and our results depend on the timers being
803806-- started at the same time. We can say that 'ParallelT' is almost the same
804−-- (modulo some implementation differences) as 'CoparAheadT' when the latter is
807+-- (modulo some implementation differences) as 'WAsyncT' when the latter is
805808-- used with unlimited lookahead and zero latency in initiating lookahead.
806809--
807810-- @
808−-- main = ('toList' . 'asParallel' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
811+-- main = ('toList' . 'parallely' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
809812-- @
810813-- @
811814-- [1,3,2,4]
812815-- @
813816--
814817-- When streams with more than one element are merged, it yields whichever
815−-- stream yields first without any bias, unlike the 'ParAhead' style streams.
818+-- stream yields first without any bias, unlike the 'Async' style streams.
816819--
817820-- Any exceptions generated by a constituent stream are propagated to the
818821-- output stream. The output and exceptions from a single stream are guaranteed
@@ -828,7 +831,7 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
828831-- import "Streamly"
829832-- import Control.Concurrent
830833--
831−-- main = 'runStream' . 'asParallel' $ do
834+-- main = 'runStream' . 'parallely' $ do
832835-- n <- return 3 \<\> return 2 \<\> return 1
833836-- liftIO $ do
834837-- threadDelay (n * 1000000)
@@ -860,17 +863,17 @@ instance IsStream ParallelT where
860863--
861864-- @since 0.2.0
862865{-# INLINE parallel #-}
863−parallel :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
866+parallel :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
864867parallel m1 m2 = fromStream $ S.parallel (toStream m1) (toStream m2)
865868
866−instance MonadParallel m => Semigroup (ParallelT m a) where
869+instance MonadAsync m => Semigroup (ParallelT m a) where
867870 (<>) = parallel
868871
869872------------------------------------------------------------------------------
870873-- Monoid
871874------------------------------------------------------------------------------
872875
873−instance MonadParallel m => Monoid (ParallelT m a) where
876+instance MonadAsync m => Monoid (ParallelT m a) where
874877 mempty = nil
875878 mappend = (<>)
876879
@@ -878,7 +881,7 @@ instance MonadParallel m => Monoid (ParallelT m a) where
878881-- Monad
879882------------------------------------------------------------------------------
880883
881−instance MonadParallel m => Monad (ParallelT m) where
884+instance MonadAsync m => Monad (ParallelT m) where
882885 return = pure
883886 (ParallelT m) >>= f = ParallelT $ parbind S.parallel m (getParallelT . f)
884887
@@ -893,12 +896,12 @@ MONAD_COMMON_INSTANCES(ParallelT, MONADPARALLEL)
893896-- Serially Zipping Streams
894897------------------------------------------------------------------------------
895898
896−-- | The applicative instance of 'ZipStreamM' zips a number of streams serially
899+-- | The applicative instance of 'ZipSerialM' zips a number of streams serially
897900-- i.e. it produces one element from each stream serially and then zips all
898901-- those elements.
899902--
900903-- @
901−-- main = (toList . 'asZipStream' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
904+-- main = (toList . 'zipSerially' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
902905-- where s1 = fromFoldable [1, 2]
903906-- s2 = fromFoldable [3, 4]
904907-- s3 = fromFoldable [5, 6]
@@ -908,29 +911,34 @@ MONAD_COMMON_INSTANCES(ParallelT, MONADPARALLEL)
908911-- @
909912--
910913-- The 'Semigroup' instance of this type works the same way as that of
911−-- 'StreamT'.
914+-- 'SerialT'.
912915--
913916-- @since 0.2.0
914−newtype ZipStreamM m a = ZipStreamM {getZipStreamM :: S.Stream m a}
917+newtype ZipSerialM m a = ZipSerialM {getZipSerialM :: S.Stream m a}
915918 deriving (Functor, Semigroup, Monoid)
916919
917−instance IsStream ZipStreamM where
918− toStream = getZipStreamM
919− fromStream = ZipStreamM
920+-- |
921+-- @since 0.1.0
922+{-# DEPRECATED ZipStream "Please use 'ZipSerialM' instead." #-}
923+type ZipStream = ZipSerialM
920924
921−instance Monad m => Applicative (ZipStreamM m) where
922− pure = ZipStreamM . S.repeat
925+instance IsStream ZipSerialM where
926+ toStream = getZipSerialM
927+ fromStream = ZipSerialM
928+
929+instance Monad m => Applicative (ZipSerialM m) where
930+ pure = ZipSerialM . S.repeat
923931 m1 <*> m2 = fromStream $ S.zipWith id (toStream m1) (toStream m2)
924932
925933------------------------------------------------------------------------------
926934-- Parallely Zipping Streams
927935------------------------------------------------------------------------------
928936
929−-- | Like 'ZipStreamM' but zips in parallel, it generates all the elements to
937+-- | Like 'ZipSerialM' but zips in parallel, it generates all the elements to
930938-- be zipped concurrently.
931939--
932940-- @
933−-- main = (toList . 'asZipParallel' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
941+-- main = (toList . 'zipAsyncly' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
934942-- where s1 = fromFoldable [1, 2]
935943-- s2 = fromFoldable [3, 4]
936944-- s3 = fromFoldable [5, 6]
@@ -940,24 +948,19 @@ instance Monad m => Applicative (ZipStreamM m) where
940948-- @
941949--
942950-- The 'Semigroup' instance of this type works the same way as that of
943−-- 'StreamT'.
951+-- 'SerialT'.
944952--
945953-- @since 0.2.0
946−newtype ZipParallelM m a = ZipParallelM {getZipParallelM :: S.Stream m a}
954+newtype ZipAsyncM m a = ZipAsyncM {getZipAsyncM :: S.Stream m a}
947955 deriving (Functor, Semigroup, Monoid)
948956
949−-- |
950−-- @since 0.1.0
951−{-# DEPRECATED ZipAsync "Please use ZipParallelM instead." #-}
952−type ZipAsync = ZipParallelM
953−
954−instance IsStream ZipParallelM where
955− toStream = getZipParallelM
956− fromStream = ZipParallelM
957+instance IsStream ZipAsyncM where
958+ toStream = getZipAsyncM
959+ fromStream = ZipAsyncM
957960
958−instance MonadParallel m => Applicative (ZipParallelM m) where
959− pure = ZipParallelM . S.repeat
960− m1 <*> m2 = fromStream $ S.zipParallelWith id (toStream m1) (toStream m2)
961+instance MonadAsync m => Applicative (ZipAsyncM m) where
962+ pure = ZipAsyncM . S.repeat
963+ m1 <*> m2 = fromStream $ S.zipAsyncWith id (toStream m1) (toStream m2)
961964
962965-------------------------------------------------------------------------------
963966-- Type adapting combinators
@@ -969,89 +972,68 @@ instance MonadParallel m => Applicative (ZipParallelM m) where
969972adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
970973adapt = fromStream . toStream
971974
972−-- | Fix the type of a polymorphic stream as 'StreamT'.
973−--
974−-- @since 0.2.0
975−asStream :: IsStream t => StreamT m a -> t m a
976−asStream = adapt
977−
978−-- | Same as 'asStream'.
975+-- | Fix the type of a polymorphic stream as 'SerialT'.
979976--
980977-- @since 0.1.0
981−{-# DEPRECATED serially "Please use asStream instead." #-}
982−serially :: IsStream t => StreamT m a -> t m a
983−serially = asStream
978+serially :: IsStream t => SerialT m a -> t m a
979+serially = adapt
984980
985−-- | Fix the type of a polymorphic stream as 'CostreamT'.
981+-- | Fix the type of a polymorphic stream as 'WSerialT'.
986982--
987983-- @since 0.2.0
988−asCostream :: IsStream t => CostreamT m a -> t m a
989−asCostream = adapt
984+wSerially :: IsStream t => WSerialT m a -> t m a
985+wSerially = adapt
990986
991−-- | Same as 'asCostream'.
987+-- | Same as 'wSerially'.
992988--
993989-- @since 0.1.0
994−{-# DEPRECATED interleaving "Please use asCostream instead." #-}
995−interleaving :: IsStream t => CostreamT m a -> t m a
996−interleaving = asCostream
990+{-# DEPRECATED interleaving "Please use wSerially instead." #-}
991+interleaving :: IsStream t => WSerialT m a -> t m a
992+interleaving = wSerially
997993
998−-- | Fix the type of a polymorphic stream as 'ParAheadT'.
999−--
1000−-- @since 0.2.0
1001−asParAhead :: IsStream t => ParAheadT m a -> t m a
1002−asParAhead = adapt
1003−
1004−-- | Same as 'asParAhead'.
994+-- | Fix the type of a polymorphic stream as 'AsyncT'.
1005995--
1006996-- @since 0.1.0
1007−{-# DEPRECATED asyncly "Please use asParAhead instead." #-}
1008−asyncly :: IsStream t => ParAheadT m a -> t m a
1009−asyncly = asParAhead
997+asyncly :: IsStream t => AsyncT m a -> t m a
998+asyncly = adapt
1010999
1011−-- | Fix the type of a polymorphic stream as 'CoparAheadT'.
1000+-- | Fix the type of a polymorphic stream as 'WAsyncT'.
10121001--
1013−-- @since 0.1.0
1014−asCoparAhead :: IsStream t => CoparAheadT m a -> t m a
1015−asCoparAhead = adapt
1002+-- @since 0.2.0
1003+wAsyncly :: IsStream t => WAsyncT m a -> t m a
1004+wAsyncly = adapt
10161005
10171006-- | Fix the type of a polymorphic stream as 'ParallelT'.
10181007--
10191008-- @since 0.1.0
1020−asParallel :: IsStream t => ParallelT m a -> t m a
1021−asParallel = adapt
1022−
1023−-- | Same as 'asParallel'.
1024−--
1025−-- @since 0.1.0
1026−{-# DEPRECATED parallely "Please use asParallel instead." #-}
10271009parallely :: IsStream t => ParallelT m a -> t m a
1028−parallely = asParallel
1010+parallely = adapt
10291011
1030−-- | Fix the type of a polymorphic stream as 'ZipStreamM'.
1012+-- | Fix the type of a polymorphic stream as 'ZipSerialM'.
10311013--
10321014-- @since 0.2.0
1033−asZipStream :: IsStream t => ZipStreamM m a -> t m a
1034−asZipStream = adapt
1015+zipSerially :: IsStream t => ZipSerialM m a -> t m a
1016+zipSerially = adapt
10351017
1036−-- | Same as 'asZipStream'.
1018+-- | Same as 'zipSerially'.
10371019--
10381020-- @since 0.1.0
1039−{-# DEPRECATED zipping "Please use asZipStream instead." #-}
1040−zipping :: IsStream t => ZipStreamM m a -> t m a
1041−zipping = asZipStream
1021+{-# DEPRECATED zipping "Please use zipSerially instead." #-}
1022+zipping :: IsStream t => ZipSerialM m a -> t m a
1023+zipping = zipSerially
10421024
1043−-- | Fix the type of a polymorphic stream as 'ZipParallelM'.
1025+-- | Fix the type of a polymorphic stream as 'ZipAsyncM'.
10441026--
10451027-- @since 0.2.0
1046−asZipParallel :: IsStream t => ZipParallelM m a -> t m a
1047−asZipParallel = adapt
1028+zipAsyncly :: IsStream t => ZipAsyncM m a -> t m a
1029+zipAsyncly = adapt
10481030
1049−-- | Same as 'asZipParallel'.
1031+-- | Same as 'zipAsyncly'.
10501032--
10511033-- @since 0.1.0
1052−{-# DEPRECATED zippingAsync "Please use asZipParallel instead." #-}
1053−zippingAsync :: IsStream t => ZipParallelM m a -> t m a
1054−zippingAsync = asZipParallel
1034+{-# DEPRECATED zippingAsync "Please use zipAsyncly instead." #-}
1035+zippingAsync :: IsStream t => ZipAsyncM m a -> t m a
1036+zippingAsync = zipAsyncly
10551037
10561038-------------------------------------------------------------------------------
10571039-- Running Streams, convenience functions specialized to types
@@ -1061,71 +1043,71 @@ zippingAsync = asZipParallel
10611043--
10621044-- @since 0.1.0
10631045{-# DEPRECATED runStreamT "Please use runStream instead." #-}
1064−runStreamT :: Monad m => StreamT m a -> m ()
1046+runStreamT :: Monad m => SerialT m a -> m ()
10651047runStreamT = runStream
10661048
1067−-- | Same as @runStream . asCostream@.
1049+-- | Same as @runStream . wSerially@.
10681050--
10691051-- @since 0.1.0
10701052{-# DEPRECATED runInterleavedT "Please use 'runStream . interleaving' instead." #-}
10711053runInterleavedT :: Monad m => InterleavedT m a -> m ()
1072−runInterleavedT = runStream . asCostream
1054+runInterleavedT = runStream . wSerially
10731055
1074−-- | Same as @runStream . asParAhead@.
1056+-- | Same as @runStream . asyncly@.
10751057--
10761058-- @since 0.1.0
1077−{-# DEPRECATED runAsyncT "Please use 'runStream . asParAhead' instead." #-}
1078−runAsyncT :: Monad m => ParAheadT m a -> m ()
1079−runAsyncT = runStream . asParAhead
1059+{-# DEPRECATED runAsyncT "Please use 'runStream . asyncly' instead." #-}
1060+runAsyncT :: Monad m => AsyncT m a -> m ()
1061+runAsyncT = runStream . asyncly
10801062
1081−-- | Same as @runStream . asParallel@.
1063+-- | Same as @runStream . parallely@.
10821064--
10831065-- @since 0.1.0
1084−{-# DEPRECATED runParallelT "Please use 'runStream . asParallel' instead." #-}
1066+{-# DEPRECATED runParallelT "Please use 'runStream . parallely' instead." #-}
10851067runParallelT :: Monad m => ParallelT m a -> m ()
1086−runParallelT = runStream . asParallel
1068+runParallelT = runStream . parallely
10871069
10881070-- | Same as @runStream . zipping@.
10891071--
10901072-- @since 0.1.0
1091−{-# DEPRECATED runZipStream "Please use 'runStream . asZipStream instead." #-}
1092−runZipStream :: Monad m => ZipStreamM m a -> m ()
1093−runZipStream = runStream . asZipStream
1073+{-# DEPRECATED runZipStream "Please use 'runStream . zipSerially instead." #-}
1074+runZipStream :: Monad m => ZipSerialM m a -> m ()
1075+runZipStream = runStream . zipSerially
10941076
10951077-- | Same as @runStream . zippingAsync@.
10961078--
10971079-- @since 0.1.0
1098−{-# DEPRECATED runZipAsync "Please use 'runStream . asZipParallel instead." #-}
1099−runZipAsync :: Monad m => ZipParallelM m a -> m ()
1100−runZipAsync = runStream . asZipParallel
1080+{-# DEPRECATED runZipAsync "Please use 'runStream . zipAsyncly instead." #-}
1081+runZipAsync :: Monad m => ZipAsyncM m a -> m ()
1082+runZipAsync = runStream . zipAsyncly
11011083
11021084------------------------------------------------------------------------------
11031085-- IO Streams
11041086------------------------------------------------------------------------------
11051087
1106−-- | A serial IO stream of elements of type @a@. See 'StreamT' documentation
1088+-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
11071089-- for more details.
11081090--
11091091-- @since 0.2.0
1110−type Stream a = StreamT IO a
1092+type Serial a = SerialT IO a
11111093
1112−-- | An interleaving serial IO stream of elements of type @a@. See 'CostreamT'
1094+-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
11131095-- documentation for more details.
11141096--
11151097-- @since 0.2.0
1116−type Costream a = CostreamT IO a
1098+type WSerial a = WSerialT IO a
11171099
11181100-- | A demand driven left biased parallely composing IO stream of elements of
1119−-- type @a@. See 'ParAheadT' documentation for more details.
1101+-- type @a@. See 'AsyncT' documentation for more details.
11201102--
11211103-- @since 0.2.0
1122−type ParAhead a = ParAheadT IO a
1104+type Async a = AsyncT IO a
11231105
11241106-- | A round robin parallely composing IO stream of elements of type @a@.
1125−-- See 'CoparAheadT' documentation for more details.
1107+-- See 'WAsyncT' documentation for more details.
11261108--
11271109-- @since 0.2.0
1128−type CoparAhead a = CoparAheadT IO a
1110+type WAsync a = WAsyncT IO a
11291111
11301112-- | A parallely composing IO stream of elements of type @a@.
11311113-- See 'ParallelT' documentation for more details.
@@ -1136,12 +1118,12 @@ type Parallel a = ParallelT IO a
11361118-- | An IO stream whose applicative instance zips streams serially.
11371119--
11381120-- @since 0.2.0
1139−type ZipStream a = ZipStreamM IO a
1121+type ZipSerial a = ZipSerialM IO a
11401122
1141−-- | An IO stream whose applicative instance zips streams asCoparAhead.
1123+-- | An IO stream whose applicative instance zips streams wAsyncly.
11421124--
11431125-- @since 0.2.0
1144−type ZipParallel a = ZipParallelM IO a
1126+type ZipAsync a = ZipAsyncM IO a
11451127
11461128------------------------------------------------------------------------------
11471129-- Fold Utilities
@@ -1150,7 +1132,7 @@ type ZipParallel a = ZipParallelM IO a
11501132-- | A variant of 'Data.Foldable.fold' that allows you to fold a 'Foldable'
11511133-- container of streams using the specified stream sum operation.
11521134--
1153−-- @foldWith 'parAhead' $ map return [1..3]@
1135+-- @foldWith 'async' $ map return [1..3]@
11541136--
11551137-- @since 0.1.0
11561138{-# INLINABLE foldWith #-}
@@ -1162,7 +1144,7 @@ foldWith f = foldr f nil
11621144-- on a 'Foldable' container and then fold it using the specified stream sum
11631145-- operation.
11641146--
1165−-- @foldMapWith 'parAhead' return [1..3]@
1147+-- @foldMapWith 'async' return [1..3]@
11661148--
11671149-- @since 0.1.0
11681150{-# INLINABLE foldMapWith #-}
src/Streamly/Tutorial.hs+301−204
@@ -37,6 +37,9 @@ module Streamly.Tutorial
3737 -- * Streams
3838 -- $streams
3939
40+ -- * Flavors of Streams
41+ -- $flavors
42+
4043 -- * Generating Streams
4144 -- $generating
4245
@@ -51,16 +54,19 @@ module Streamly.Tutorial
5154 -- ** Semigroup Style
5255 -- $semigroup
5356
54− -- *** Serial Depth First Composition ('Stream')
57+ -- *** Deep Serial Composition ('Serial')
5558 -- $serial
5659
57− -- *** Serial Breadth First Composition ('Costream')
60+ -- *** Wide Serial Composition ('WSerial')
5861 -- $interleaved
5962
60− -- *** Concurrent Depth First Composition ('ParAhead')
61− -- $parAhead
63+ -- *** Deep Asynchronous Composition ('Async')
64+ -- $async
65+
66+ -- *** Wide Asynchronous Composition ('WAsync')
67+ -- $wasync
6268
63− -- *** Concurrent Breadth First Composition ('CoParAhead')
69+ -- *** Parallel Asynchronous Composition ('Parallel')
6470 -- $parallel
6571
6672 -- *** Custom composition
@@ -75,17 +81,20 @@ module Streamly.Tutorial
7581 -- ** Monad
7682 -- $monad
7783
78− -- *** Serial Depth First Nesting ('Stream')
84+ -- *** Deep Serial Nesting ('Serial')
7985 -- $regularSerial
8086
81− -- *** Serial Breadth First Nesting ('Costream')
87+ -- *** Wide Serial Nesting ('WSerial')
8288 -- $interleavedNesting
8389
84− -- *** Concurrent Depth First Nesting ('ParAhead')
90+ -- *** Deep Asynchronous Nesting ('Async')
8591 -- $concurrentNesting
8692
87− -- *** Concurrent Breadth First Nesting ('CoparAhead')
88− -- $fairlyConcurrentNesting
93+ -- *** Wide Asynchronous Nesting ('WAsync')
94+ -- $wasyncNesting
95+
96+ -- *** Parallel Asynchronous Nesting ('Parallel')
97+ -- $parallelNesting
8998
9099 -- *** Exercise
91100 -- $monadExercise
@@ -105,9 +114,6 @@ module Streamly.Tutorial
105114 -- ** Parallel Zipping
106115 -- $parallelzip
107116
108− -- * Summary of Compositions
109− -- $compositionSummary
110−
111117 -- * Monad transformers
112118 -- $monadtransformers
113119
@@ -149,47 +155,90 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
149155-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
150156-- appending streams of arbitrary length is scalable and inexpensive.
151157--
152−-- The basic stream type is 'Stream', it represents a sequence of IO actions,
153−-- and is a 'Monad'. The type 'StreamT' is a monad transformer that can
154−-- represent a sequence of actions in an arbitrary monad. The type 'Stream' is
155−-- in fact a synonym for @StreamT IO@. There are a few more types similar to
156−-- 'StreamT' that all represent streams and differ only in the 'Semigroup',
157−-- 'Applicative' and 'Monad' compositions of the streams. 'Stream' and
158−-- 'Costream' types compose serially whereas 'ParAhead' and 'CoparAhead' types
159−-- compose concurrently. All these types can be freely inter-converted using
160−-- type combinators without any cost. You can freely switch to any type of
161−-- composition at any point in the program. When no type annotation or
162−-- explicit stream type combinators are used, the default stream type is
163−-- inferred as 'Stream'.
164−--
165−-- The 'Stream' monad is almost a drop in replacement for the 'IO' monad, IO
166−-- monad is a special case of the 'Stream' monad; IO monad represents a single
167−-- IO action whereas the 'Stream' monad represents a sequence of IO actions.
168−-- The only change you need to make to go from 'IO' to 'Stream' is to use
169−-- 'runStream' to run the monad and to prefix the IO actions with 'once'. You
170−-- can also use 'liftIO' instead of 'once'. In fact, if you use liftIO you can
171−-- switch from 'Stream' to IO monad by simply removing the 'runStream'
172−-- function; no other changes are needed unless you have used some stream
173−-- specific composition or combinators.
174−--
175−-- Similarly, the 'Stream' type is almost a drop in replacement for pure lists,
158+-- The basic stream type is 'Serial', it represents a sequence of IO actions,
159+-- and is a 'Monad'. The 'Serial' monad is almost a drop in replacement for
160+-- the 'IO' monad, IO monad is a special case of the 'Serial' monad; IO monad
161+-- represents a single IO action whereas the 'Serial' monad represents a series
162+-- of IO actions. The only change you need to make to go from 'IO' to 'Serial'
163+-- is to use 'runStream' to run the monad and to prefix the IO actions with
164+-- either 'once' or 'liftIO'. If you use liftIO you can switch from 'Serial'
165+-- to IO monad by simply removing the 'runStream' function; no other changes
166+-- are needed unless you have used some stream specific composition or
167+-- combinators.
168+--
169+-- Similarly, the 'Serial' type is almost a drop in replacement for pure lists,
176170-- pure lists are a special case of monadic streams. If you use 'nil' in place
177−-- of '[]' and '|:' in place ':' you can replace a list with a 'Stream'. The
171+-- of '[]' and '|:' in place ':' you can replace a list with a 'Serial' The
178172-- only difference is that the elements must be monadic type and to operate on
179173-- the streams we must use the corresponding functions from "Streamly.Prelude"
180174-- instead of using the base "Prelude".
181175
176+-- $flavors
177+--
178+-- There are a few more types similar to 'Serial' that all represent streams
179+-- and differ only in the 'Semigroup', 'Applicative' and 'Monad' compositions
180+-- of the streams.
181+--
182+-- The composition of two or more streams is distinguished based on three
183+-- characterstics, /traversal order/, /execution order/ and
184+-- /consumption order/. Traversal of a composition of streams could be @deep@
185+-- or @wide@. Deep goes depth first i.e. each stream is traversed fully
186+-- before we traverse the next stream. Wide goes breadth first i.e. one element
187+-- from each stream is traversed before coming back to the first stream again.
188+-- Execution could be serial (i.e. synchronous) or asynchronous. In serial
189+-- execution we execute an action in the next stream only after the first has
190+-- finished executing. In asynchronous execution actions in both streams can be
191+-- executed asynchronously i.e. the next action can start executing even before
192+-- the first one has finished. The third parameter is consumption order that is
193+-- in what order the output generated by the composition is consumed.
194+-- Consumption could be serial or asynchronous. In serial consumption, the
195+-- outputs are consumed in the traversal order, in asynchronous consumption the
196+-- outputs are consumed as they arrive i.e. first come first serve order.
197+--
198+-- The following table summarizes different styles of streams based on how they
199+-- compose. All these types are monads and they differ in 'Semigroup',
200+-- 'Applicative' and 'Monad' compositions:
201+--
202+-- @
203+-- +------------+-----------+--------------+--------------+
204+-- | Type | Traversal | Execution | Consumption |
205+-- +============+===========+==============+==============+
206+-- | 'Serial' | Deep | Serial | Serial |
207+-- +------------+-----------+--------------+--------------+
208+-- | 'WSerial' | Wide | Serial | Serial |
209+-- +------------+-----------+--------------+--------------+
210+-- | 'Async' | Deep | Asynchronous | Asynchronous |
211+-- +------------+-----------+--------------+--------------+
212+-- | 'WAsync' | Wide | Asynchronous | Asynchronous |
213+-- +------------+-----------+--------------+--------------+
214+-- | 'Parallel' | Parallel | Asynchronous | Asynchronous |
215+-- +------------+-----------+--------------+--------------+
216+-- @
217+--
218+-- Other than these types there are also 'ZipSerial' and 'ZipAsync' types that
219+-- zip streams serially or concurrently using 'Applicative' operation. These
220+-- types are not monads they are only applicatives and they do not differ in
221+-- 'Semigroup' composition.
222+--
223+-- All these types can be freely inter-converted using type conversion
224+-- combinators or type annotations without any cost, to acheive the desired
225+-- composition style. To force a particular type of composition we coerce the
226+-- stream type using the corresponding type adapting combinator from
227+-- 'serially', 'wSerially', 'asyncly', 'wAsyncly', 'parallely', 'zipSerially'
228+-- or 'zipAsyncly'. The default stream type is inferred as 'Serial' unless you
229+-- change it by using one of the combinators or using a type annotation.
230+
182231-- $monadtransformers
183232--
184233-- To represent streams in an arbitrary monad use the more general monad
185234-- transformer types for example the monad transformer type corresponding to
186−-- the 'Stream' type is 'StreamT'. @StreamT m a@ represents a stream of values
187−-- of type 'a' in some underlying monad 'm'. For example, @StreamT IO Int@ is a
188−-- stream of 'Int' in 'IO' monad. In fact, the type 'Stream' is a synonym for
189−-- @StreamT IO@.
235+-- the 'Serial' type is 'SerialT'. @SerialT m a@ represents a stream of values
236+-- of type 'a' in some underlying monad 'm'. For example, @SerialT IO Int@ is a
237+-- stream of 'Int' in 'IO' monad. In fact, the type 'Serial' is a synonym for
238+-- @SerialT IO@.
190239--
191240-- Similarly we have monad transformer types for other stream types as well viz.
192−-- 'CostreamT', 'ParAheadT' and 'CoparAheadT'.
241+-- 'WSerialT', 'AsyncT', 'WAsyncT' and 'ParallelT'.
193242--
194243-- To lift a value from an underlying monad in a monad transformer stack into a
195244-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
@@ -307,17 +356,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
307356-- We can combine two streams into a single stream using semigroup composition
308357-- operation '<>'. Streams can be combined in many different ways as described
309358-- in the following sections, the '<>' operation behaves differently depending
310−-- on the stream type in effect. Streamly streams can be of many
311−-- different types i.e. 'Stream', 'Costream', 'ParAhead', 'CoparAhead',
312−-- 'ZipStream', and 'ZipParallel'. The first four are monads whereas the last
313−-- two are applicatives. These types can be freely converted from one to
314−-- another to acheive the desired composition style. To force a particular
315−-- type of composition we coerce the stream type using the corresponding type
316−-- adapting combinator from 'asStream', 'asCostream', 'asParAhead',
317−-- 'asCoparAhead', 'asZipStream' or 'asZipParallel'. The default stream type is
318−-- 'Stream' unless you change it by using one of the combinators.
319−--
320−-- To illustrate the concurrent vs serial composition aspects, we will use the
359+-- on the stream type in effect. The stream type and therefore the composition
360+-- style can be changed at any point using one of the type combinators as
361+-- discussed earlier.
362+--
363+-- To illustrate concurrent vs serial composition aspects, we will use the
321364-- following @delay@ function to introduce a delay specified in seconds.
322365--
323366-- @
@@ -334,11 +377,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
334377
335378-- $serial
336379--
337−-- The 'Semigroup' operation '<>' of the 'Stream' type combines the two streams
338−-- in a /serial depth first/ manner. We use the 'asStream' type combinator to
339−-- effect 'Stream' style of composition. We can also use an explicit 'Stream'
380+-- The 'Semigroup' operation '<>' of the 'Serial' type combines the two streams
381+-- in a /serial depth first/ manner. We use the 'serially' type combinator to
382+-- effect 'Serial' style of composition. We can also use an explicit 'Serial'
340383-- type annotation for the stream to acheive the same effect. However, since
341−-- 'Stream' is the default type unless explicitly specified by using a
384+-- 'Serial' is the default type unless explicitly specified by using a
342385-- combinator, we can omit using an explicit combinator or type annotation for
343386-- this style of composition.
344387--
@@ -362,7 +405,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
362405--
363406-- All actions in both the streams are performed serially in the same thread.
364407-- In the following example we can see that all actions are performed in the
365−-- same thread and take a combined total of 6 seconds:
408+-- same thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
366409--
367410-- @
368411-- main = 'runStream' $ delay 3 <> delay 2 <> delay 1
@@ -373,20 +416,20 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
373416-- ThreadId 36: Delay 1
374417-- @
375418--
376−-- The polymorphic version of the 'Stream' binary operation '<>' is called
377−-- 'splice'. We can use 'splice' to join streams in a sequential manner
419+-- The polymorphic version of the binary operation '<>' of the 'Serial' type is
420+-- 'serial'. We can use 'serial' to join streams in a sequential manner
378421-- irrespective of the type of stream:
379422--
380423-- @
381−-- main = 'runStream' $ (print 1 |: print 2 |: nil) \`splice` (print 3 |: print 4 |: nil)
424+-- main = 'runStream' $ (print 1 |: print 2 |: nil) \`serial` (print 3 |: print 4 |: nil)
382425-- @
383426
384427-- $interleaved
385428--
386−-- The 'Semigroup' operation '<>' of the 'Costream' type combines the two
387−-- streams in a /serial breadth first/ manner. We use the 'asCostream' type
388−-- combinator to effect 'Costream' style of composition. We can also use the
389−-- 'Costream' type annotation for the stream to acheive the same effect.
429+-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
430+-- streams in a /serial breadth first/ manner. We use the 'wSerially' type
431+-- combinator to effect 'WSerial' style of composition. We can also use the
432+-- 'WSerial' type annotation for the stream to acheive the same effect.
390433--
391434-- When two streams with multiple elements are combined in this manner, we
392435-- traverse all the streams in a breadth first manner i.e. one action from each
@@ -395,7 +438,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
395438-- The following example prints the sequence 1, 3, 2, 4
396439--
397440-- @
398−-- main = 'runStream' . 'asCostream' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
441+-- main = 'runStream' . 'wSerially' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
399442-- @
400443-- @
401444-- 1
@@ -407,10 +450,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
407450-- Even though the monadic actions of the two streams are performed in an
408451-- interleaved manner they are all performed serially in the same thread. In
409452-- the following example we can see that all actions are performed in the same
410−-- thread and take a combined total of 6 seconds:
453+-- thread and take a combined total of @3 + 2 + 1 = 6@ seconds:
411454--
412455-- @
413−-- main = 'runStream' . 'asCostream' $ delay 3 <> delay 2 <> delay 1
456+-- main = 'runStream' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
414457-- @
415458-- @
416459-- ThreadId 36: Delay 3
@@ -418,13 +461,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
418461-- ThreadId 36: Delay 1
419462-- @
420463--
421−-- The polymorphic version of the 'Costream' binary operation '<>' is called
422−-- 'cosplice'. We can use 'cosplice' to join streams in an interleaved manner
423−-- irrespective of the type, notice that we have not used the 'asCostream'
464+-- The polymorphic version of the 'WSerial' binary operation '<>' is called
465+-- 'wSerial'. We can use 'wSerial' to join streams in an interleaved manner
466+-- irrespective of the type, notice that we have not used the 'wSerially'
424467-- combinator in the following example:
425468--
426469-- @
427−-- main = 'runStream' $ (print 1 |: print 2 |: nil) \`cosplice` (print 3 |: print 4 |: nil)
470+-- main = 'runStream' $ (print 1 |: print 2 |: nil) \`wSerial` (print 3 |: print 4 |: nil)
428471-- @
429472-- @
430473-- 1
@@ -436,16 +479,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
436479-- Note that this composition cannot be used to fold infinite number of streams
437480-- since it requires preserving the state until a stream is finished.
438481
439−-- $parAhead
482+-- $async
440483--
441−-- The 'Semigroup' operation '<>' of the 'ParAhead' type combines the two
484+-- The 'Semigroup' operation '<>' of the 'Async' type combines the two
442485-- streams in a depth first manner with parallel look ahead. We use the
443−-- 'asParAhead' type combinator to effect 'ParAhead' style of composition. We
444−-- can also use the 'ParAhead' type annotation for the stream type to acheive
486+-- 'asyncly' type combinator to effect 'Async' style of composition. We
487+-- can also use the 'Async' type annotation for the stream type to acheive
445488-- the same effect.
446489--
447490-- When two streams with multiple elements are combined in this manner, the
448−-- streams are traversed in depth first manner just like 'Stream', however it
491+-- streams are traversed in depth first manner just like 'Serial', however it
449492-- can execute the next stream concurrently and return the results from it
450493-- as they arrive i.e. the results from the next stream may be yielded even
451494-- before the results from the first stream. Concurrent execution of the next
@@ -456,7 +499,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
456499-- therefore the first stream is completely exhausted before the second.
457500--
458501-- @
459−-- main = 'runStream' . 'asParAhead' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
502+-- main = 'runStream' . 'asyncly' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
460503-- @
461504-- @
462505-- 1
@@ -470,7 +513,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
470513-- and 3 would be yielded first and then 2 and 4 would be yielded.
471514--
472515-- @
473−-- main = 'runStream' . 'asParAhead' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
516+-- main = 'runStream' . 'asyncly' $ (p 1 |: p 2 |: nil) <> (p 3 |: p 4 |: nil)
474517-- where p n = threadDelay 1000000 >> print n
475518-- @
476519-- @
@@ -482,10 +525,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
482525--
483526-- In the following example we can see that new threads are started when a
484527-- computation blocks. Notice that the output from the stream with the
485−-- shortest delay is printed first:
528+-- shortest delay is printed first. The whole computation takes @maximum of
529+-- (3, 2, 1) = 3@ seconds:
486530--
487531-- @
488−-- main = 'runStream' . 'asParAhead' $ delay 3 '<>' delay 2 '<>' delay 1
532+-- main = 'runStream' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
489533-- @
490534-- @
491535-- ThreadId 42: Delay 1
@@ -494,7 +538,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
494538-- @
495539--
496540-- When we have a tree of computations composed using this style, the tree is
497−-- traversed in DFS style just like the serial style, the only difference is
541+-- traversed in DFS style just like the 'Serial' style, the only difference is
498542-- that here we can move on to executing the next stream if a stream blocks.
499543-- However, we will not start new threads if we have sufficient output to
500544-- saturate the consumer. This is why we call it left-biased demand driven or
@@ -504,7 +548,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
504548-- second as all of the actions are concurrent.
505549--
506550-- @
507−-- main = 'runStream' . 'asParAhead' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
551+-- main = 'runStream' . 'asyncly' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
508552-- @
509553-- @
510554-- 1
@@ -521,7 +565,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
521565-- even if none of them blocks:
522566--
523567-- @
524−-- main = 'runStream' . 'asParAhead' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
568+-- main = 'runStream' . 'asyncly' $ traced (sqrt 9) '<>' traced (sqrt 16) '<>' traced (sqrt 25)
525569-- where traced m = S.'once' (myThreadId >>= print) >> return m
526570-- @
527571-- @
@@ -533,13 +577,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
533577-- Note that the order of printing in the above examples may change due to
534578-- variations in scheduling latencies for concurrent threads.
535579--
536−-- The polymorphic version of the 'ParAhead' binary operation '<>' is called
537−-- 'parAhead'. We can use 'parAhead' to join streams in a left biased
580+-- The polymorphic version of the 'Async' binary operation '<>' is called
581+-- 'async'. We can use 'async' to join streams in a left biased
538582-- adaptively concurrent manner irrespective of the type, notice that we have
539−-- not used the 'asParAhead' combinator in the following example:
583+-- not used the 'asyncly' combinator in the following example:
540584--
541585-- @
542−-- main = 'runStream' $ delay 3 \`parAhead` delay 2 \`parAhead` delay 1
586+-- main = 'runStream' $ delay 3 \`async` delay 2 \`async` delay 1
543587-- @
544588-- @
545589-- ThreadId 42: Delay 1
@@ -555,27 +599,80 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
555599-- all computations at once for any reason 'Parallel' style must be used
556600-- instead.
557601--
558−-- 'ParAhead' style should be preferred over 'CoparAhead' unless you really
559−-- need 'CoparAhead'. It utilizes the resources optimally. It should be used when
560−-- we know that the computations can run in parallel but we do not care if they
561−-- actually run in parallel or not, that decision can be left to the scheduler
562−-- based on demand. Also, note that this operator can be used to fold infinite
563−-- number of streams in contrast to the 'CoparAhead' style, because it does not
564−-- require us to run all of them at the same time in a fair manner.
602+-- 'Async' style should be preferred over 'Parallel' or 'WAsync' unless you
603+-- really need those. It utilizes the resources optimally. It should be used
604+-- when we know that the computations can run in parallel but we do not care if
605+-- they actually run in parallel or not, that decision can be left to the
606+-- scheduler based on demand. Also, note that this operator can be used to fold
607+-- infinite number of streams in contrast to the 'Parallel' or 'WAsync' styles,
608+-- because it does not require us to run all of them at the same time in a fair
609+-- manner.
610+
611+-- $wasync
612+--
613+-- The 'Semigroup' operation '<>' of the 'WAsync' type combines two streams in
614+-- a concurrent manner using /breadth first traversal/. We use the 'wAsyncly'
615+-- type combinator to effect 'WAsync' style of composition. We can also use the
616+-- 'WAsync' type annotation for the stream to acheive the same effect.
617+--
618+-- When streams with multiple elements are combined in this manner, we traverse
619+-- all the streams concurrently in a breadth first manner i.e. one action from
620+-- each stream is peformed and yielded to the resulting stream before we come
621+-- back to the first stream again and so on. Even though we execute the actions
622+-- in a breadth first order the outputs may be consumed in a different order
623+-- because they are consumed on a first come first serve basis.
624+--
625+-- In the following example we can see that outputs are produced in the breadth
626+-- first travresal order but this is not guaranteed.
627+--
628+-- @
629+-- main = 'runStream' . 'wAsyncly' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
630+-- @
631+-- @
632+-- 1
633+-- 3
634+-- 2
635+-- 4
636+-- @
637+--
638+-- The polymorphic version of the binary operation '<>' of the 'WAsync' type is
639+-- 'wAsync'. We can use 'wAsync' to join streams using a breadth first
640+-- concurrent traversal irrespective of the type, notice that we have not used
641+-- the 'wAsyncly' combinator in the following example:
642+--
643+-- @
644+-- main = 'runStream' $ delay 3 \`wAsync` delay 2 \`wAsync` delay 1
645+-- @
646+-- @
647+-- ThreadId 42: Delay 1
648+-- ThreadId 41: Delay 2
649+-- ThreadId 40: Delay 3
650+-- @
651+--
652+-- Since the concurrency provided by this style is demand driven it may not
653+-- be used when the composed computations start timers that are relative to
654+-- each other because all computations may not be started at the same time and
655+-- therefore timers in all of them may not start at the same time. When
656+-- relative timing among all computations is important or when we need to start
657+-- all computations at once for any reason 'Parallel' style must be used
658+-- instead.
659+--
565660
566661-- $parallel
567662--
568663-- The 'Semigroup' operation '<>' of the 'Parallel' type combines the two
569664-- streams in a fairly concurrent manner with round robin scheduling. We use
570−-- the 'parallel' type combinator to effect 'Parallel' style of composition. We
571−-- can also use the 'Parallel' type annotation for the stream type to acheive
572−-- the same effect.
665+-- the 'parallely' type combinator to effect 'Parallel' style of composition.
666+-- We can also use the 'Parallel' type annotation for the stream type to
667+-- acheive the same effect.
573668--
574669-- When two streams with multiple elements are combined in this manner, the
575670-- monadic actions in both the streams are performed concurrently with a fair
576671-- round robin scheduling. The outputs are yielded in the order in which the
577−-- actions complete. This can be thought of as the concurrent analogue of the
578−-- 'Costream' style serial composition.
672+-- actions complete. This is pretty similar to the 'WAsync' type, the
673+-- difference is that 'WAsync' is adaptive to the consumer demand and may or
674+-- may not execute all actions in parallel depending on the demand, whereas
675+-- 'Parallel' runs all the streams in parallel irrespective of the demand.
579676--
580677-- The following example sends a query to all the three search engines in
581678-- parallel and prints the name of the search engines in the order in which the
@@ -586,7 +683,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
586683-- import qualified Streamly.Prelude as S
587684-- import Network.HTTP.Simple
588685--
589−-- main = 'runStream' . 'asParallel' $ google \<> bing \<> duckduckgo
686+-- main = 'runStream' . 'parallely' $ google \<> bing \<> duckduckgo
590687-- where
591688-- google = get "https://www.google.com/search?q=haskell"
592689-- bing = get "https://www.bing.com/search?q=haskell"
@@ -594,27 +691,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
594691-- get s = S.'once' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
595692-- @
596693--
597−-- In the following example we can see that the co-ahead parallel composition
598−-- yields outputs in the same order as the 'Costream' composition, though this
599−-- is not always guaranteed because of thread scheduling variances.
600−--
601−-- @
602−-- main = 'runStream' . 'asCoparAhead' $ (print 1 |: print 2 |: nil) <> (print 3 |: print 4 |: nil)
603−-- @
604−-- @
605−-- 1
606−-- 3
607−-- 2
608−-- 4
609−-- @
610−--
611−-- The polymorphic version of the 'CoparAhead' binary operation '<>' is called
612−-- 'coparAhead'. We can use 'coparAhead' to join streams in a fairly
613−-- concurrent manner irrespective of the type, notice that we have
614−-- not used the 'asCoparAhead' combinator in the following example:
694+-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
695+-- is 'parallel'. We can use 'parallel' to join streams in a fairly concurrent
696+-- manner irrespective of the type, notice that we have not used the
697+-- 'parallely' combinator in the following example:
615698--
616699-- @
617−-- main = 'runStream' $ delay 3 \`coparAhead` delay 2 \`coparAhead` delay 1
700+-- main = 'runStream' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
618701-- @
619702-- @
620703-- ThreadId 42: Delay 1
@@ -628,7 +711,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
628711
629712-- $custom
630713--
631−-- The 'async' API can be used to create references to asynchronously running
714+-- The 'mkAsync' API can be used to create references to asynchronously running
632715-- stream computations. We can then use 'uncons' to explore the streams
633716-- arbitrarily and then recompose individual elements to create a new stream.
634717-- This way we can dynamically decide which stream to explore at any given
@@ -660,10 +743,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
660743-- import Control.Concurrent
661744--
662745-- main = do
663−-- 'runStream' $ 'asParAhead' $ foldMap delay [1..10]
664−-- 'runStream' $ 'foldWith' 'parAhead' (map delay [1..10])
665−-- 'runStream' $ 'foldMapWith' 'parAhead' delay [1..10]
666−-- 'runStream' $ 'forEachWith' 'parAhead' [1..10] delay
746+-- 'runStream' $ 'asyncly' $ foldMap delay [1..10]
747+-- 'runStream' $ 'foldWith' 'async' (map delay [1..10])
748+-- 'runStream' $ 'foldMapWith' 'async' delay [1..10]
749+-- 'runStream' $ 'forEachWith' 'async' [1..10] delay
667750-- where delay n = S.'once' $ threadDelay (n * 1000000) >> print n
668751-- @
669752
@@ -688,18 +771,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
688771-- element in the first stream and for each element in the second stream
689772-- execute the body of the loop.
690773--
691−-- The 'Monad' instances of 'Stream', 'Costream', 'ParAhead' and 'CoparAhead'
774+-- The 'Monad' instances of 'Serial', 'WSerial', 'Async' and 'WAsync'
692775-- stream types support different flavors of nested looping. In other words,
693776-- they are all variants of list transformer. The nesting behavior of these
694−-- types exactly correspond to the way they merge streams as we discussed in
777+-- types correspond exactly to the way they merge streams as we discussed in
695778-- the previous section.
696779--
697780
698781-- $regularSerial
699782--
700−-- The 'Monad' composition of 'Stream' type behaves like a standard list
783+-- The 'Monad' composition of the 'Serial' type behaves like a standard list
701784-- transformer. This is the default when we do not use an explicit type
702−-- combinator. However, the 'streamly' type combinator can be used to switch to
785+-- combinator. However, the 'serially' type combinator can be used to switch to
703786-- this style of composition. We will see how this style of composition works
704787-- in the following examples.
705788--
@@ -722,7 +805,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
722805-- ThreadId 30: Delay 1
723806-- @
724807--
725−-- As you can see, the code after the @fromFoldable@ statement is run three
808+-- As we can see, the code after the @fromFoldable@ statement is run three
726809-- times, once for each value of @x@ drawn from the stream. All the three
727810-- iterations are serial and run in the same thread one after another. In
728811-- imperative terms this is equivalent to a @for@ loop with three iterations.
@@ -758,27 +841,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
758841-- (2,4)
759842-- @
760843--
761−-- Notice that this is analogous to merging streams of type 'Stream' or merging
762−-- streams using 'splice'.
844+-- Notice that this is analogous to merging streams of type 'Serial' or merging
845+-- streams using 'serial'.
763846
764847-- $concurrentNesting
765848--
766−-- The 'Monad' composition of 'ParAhead' type can perform the iterations of a
849+-- The 'Monad' composition of 'Async' type can perform the iterations of a
767850-- loop concurrently. Concurrency is demand driven i.e. more concurrent
768851-- iterations are started only if the previous iterations are not able to
769852-- produce enough output for the consumer of the output stream. This works
770−-- exactly the same way as the merging of two streams 'asParAhead' works.
771−-- This is the concurrent analogue of 'Stream' style monadic composition.
853+-- exactly the same way as the merging of two streams 'asyncly' works.
854+-- This is the concurrent analogue of 'Serial' style monadic composition.
772855--
773−-- The 'asParAhead' type combinator can be used to switch to this
774−-- style of composition. Alternatively, a type annotation can be used to
775−-- specify the type of the stream as 'ParAhead'.
856+-- The 'asyncly' type combinator can be used to switch to this style of
857+-- composition. Alternatively, a type annotation can be used to specify the
858+-- type of the stream as 'Async'.
776859--
777860-- @
778861-- import "Streamly"
779862-- import "Streamly.Prelude"
780863--
781−-- main = 'runStream' . 'asParAhead' $ do
864+-- main = 'runStream' . 'asyncly' $ do
782865-- x <- 'fromFoldable' [3,2,1]
783866-- delay x
784867-- @
@@ -788,24 +871,24 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
788871-- ThreadId 38: Delay 3
789872-- @
790873--
791−-- As you can see the code after the @fromFoldable@ statement is run three
874+-- As we can see the code after the @fromFoldable@ statement is run three
792875-- times, once for each value of @x@. All the three iterations are concurrent
793876-- and run in different threads. The iteration with least delay finishes first.
794877-- When compared to imperative programming, this can be viewed as a @for@ loop
795878-- with three concurrent iterations.
796879--
797−-- Concurrency is demand driven just as in the case of 'parAhead' merging.
880+-- Concurrency is demand driven just as in the case of 'async' merging.
798881-- When multiple streams are composed using this style, the iterations are
799−-- triggered in a DFS manner just like 'Stream' i.e. nested iterations are
882+-- triggered in a depth first manner just like 'Serial' i.e. nested iterations are
800883-- executed before we proceed to the next iteration at higher level. However,
801−-- unlike 'Stream' more than one iterations may be started concurrently based
802−-- on the demand from the consumer.
884+-- unlike 'Serial' more than one iterations may be started concurrently based
885+-- on the demand from the consumer of the stream.
803886--
804887-- @
805888-- import "Streamly"
806889-- import qualified "Streamly.Prelude" as S
807890--
808−-- main = 'runStream' . 'asParAhead' $ do
891+-- main = 'runStream' . 'asyncly' $ do
809892-- x <- S.'fromFoldable' [1,2]
810893-- y <- S.'fromFoldable' [3,4]
811894-- S.'once' $ putStrLn $ show (x, y)
@@ -819,18 +902,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
819902
820903-- $interleavedNesting
821904--
822−-- The 'Monad' composition of 'Costream' type interleaves the iterations of
905+-- The 'Monad' composition of 'WSerial' type interleaves the iterations of
823906-- outer and inner loops in a nested loop composition. This works exactly the
824−-- same way as the merging of two streams in 'asCostream' fashion works. The
825−-- 'asCostream' type combinator can be used to switch to this style of
907+-- same way as the merging of two streams in 'wSerially' fashion works. The
908+-- 'wSerially' type combinator can be used to switch to this style of
826909-- composition. Alternatively, a type annotation can be used to specify the
827−-- type of the stream as 'Costream'.
910+-- type of the stream as 'WSerial'.
828911--
829912-- @
830913-- import "Streamly"
831914-- import qualified "Streamly.Prelude" as S
832915--
833−-- main = 'runStream' . 'asCostream' $ do
916+-- main = 'runStream' . 'wSerially' $ do
834917-- x <- S.'fromFoldable' [1,2]
835918-- y <- S.'fromFoldable' [3,4]
836919-- S.once $ putStrLn $ show (x, y)
@@ -843,14 +926,42 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
843926-- @
844927--
845928
846−-- $fairlyConcurrentNesting
929+-- $wasyncNesting
847930--
848−-- The 'Monad' composition of 'Parallel' type starts all the iterations of a
849−-- loop concurrently instead of demand driven as in the case of 'ParAhead'.
850−-- This works exactly the same way as the merging streams 'parallely' works.
851−-- The 'parallely' type combinator can be used to switch to this style of
852−-- composition. Alternatively, a type annotation can be used to specify the
853−-- type of the stream as 'Parallel'.
931+-- Just like 'Async' the 'Monad' composition of 'WAsync' runs the iterations of
932+-- a loop concurrently. The difference is in the nested loop behavior. The
933+-- nested loops in this type are traversed and executed in a breadth first
934+-- manner rather than the depth first manner of 'Async' style.
935+-- The loop nesting works exactly the same way as the merging of streams
936+-- 'wAsyncly' works. The 'wAsyncly' type combinator can be used to switch to
937+-- this style of composition. Alternatively, a type annotation can be used to
938+-- specify the type of the stream as 'WAsync'.
939+--
940+-- @
941+-- import "Streamly"
942+-- import qualified "Streamly.Prelude" as S
943+--
944+-- main = 'runStream' . 'wAsyncly' $ do
945+-- x <- S.'fromFoldable' [1,2]
946+-- y <- S.'fromFoldable' [3,4]
947+-- S.'once' $ putStrLn $ show (x, y)
948+-- @
949+-- @
950+-- (1,3)
951+-- (2,3)
952+-- (1,4)
953+-- (2,4)
954+-- @
955+
956+-- $parallelNesting
957+--
958+-- Just like 'Async' or 'WAsync' the 'Monad' composition of 'Parallel' runs the
959+-- iterations of a loop concurrently. The difference is in the nested loop
960+-- behavior. The streams at each nest level is run fully concurrently
961+-- irrespective of the demand. The loop nesting works exactly the same way as
962+-- the merging of streams 'parallely' works. The 'parallely' type combinator
963+-- can be used to switch to this style of composition. Alternatively, a type
964+-- annotation can be used to specify the type of the stream as 'Parallel'.
854965--
855966-- @
856967-- import "Streamly"
@@ -868,7 +979,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
868979
869980-- $monadExercise
870981--
871−-- The streamly code is usually written in a way that is agnostic of the
982+-- Streamly code is usually written in a way that is agnostic of the
872983-- specific monadic composition type. We use a polymorphic type with a
873984-- 'IsStream' type class constraint. When running the stream we can choose the
874985-- specific mode of composition. For example take a look at the following code.
@@ -894,10 +1005,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
8941005-- Now we can interpret this in whatever way we want:
8951006--
8961007-- @
897−-- main = 'runStream' . 'asStream' $ composed
898−-- main = 'runStream' . 'asCostream' $ composed
899−-- main = 'runStream' . 'asParAhead' $ composed
900−-- main = 'runStream' . 'asCoparAhead' $ composed
1008+-- main = 'runStream' . 'serially' $ composed
1009+-- main = 'runStream' . 'wSerially' $ composed
1010+-- main = 'runStream' . 'asyncly' $ composed
1011+-- main = 'runStream' . 'wAsyncly' $ composed
1012+-- main = 'runStream' . 'parallely' $ composed
9011013-- @
9021014--
9031015-- As an exercise try to figure out the output of this code for each mode of
@@ -922,10 +1034,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9221034-- $applicative
9231035--
9241036-- Applicative is precisely the same as the 'ap' operation of 'Monad'. For
925−-- zipping applicatives separate types 'ZipStream' and 'ZipParallel' are
1037+-- zipping applicatives separate types 'ZipSerial' and 'ZipAsync' are
9261038-- provided.
9271039--
928−-- The following example uses the 'Stream' applicative, it runs all iterations
1040+-- The following example uses the 'Serial' applicative, it runs all iterations
9291041-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
9301042--
9311043-- @
@@ -937,7 +1049,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9371049-- s2 = d 3 <> d 4
9381050-- d n = delay n >> return n
9391051--
940−-- main = (S.'toList' . 'asStream' $ (,) \<$> s1 \<*> s2) >>= print
1052+-- main = (S.'toList' . 'serially' $ (,) \<$> s1 \<*> s2) >>= print
9411053-- @
9421054-- @
9431055-- ThreadId 36: Delay 1
@@ -949,11 +1061,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9491061-- [(1,3),(1,4),(2,3),(2,4)]
9501062-- @
9511063--
952−-- Similalrly 'Costream' applicative runs the iterations in an interleaved
1064+-- Similalrly 'WSerial' applicative runs the iterations in an interleaved
9531065-- order but since it is serial it takes a total of 17 seconds:
9541066--
9551067-- @
956−-- main = (S.'toList' . 'asCostream' $ (,) \<$> s1 \<*> s2) >>= print
1068+-- main = (S.'toList' . 'wSerially' $ (,) \<$> s1 \<*> s2) >>= print
9571069-- @
9581070-- @
9591071-- ThreadId 36: Delay 1
@@ -965,11 +1077,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9651077-- [(1,3),(2,3),(1,4),(2,4)]
9661078-- @
9671079--
968−-- 'ParAhead' can run the iterations concurrently and therefore takes a total
1080+-- 'Async' can run the iterations concurrently and therefore takes a total
9691081-- of 10 seconds (1 + 2 + 3 + 4):
9701082--
9711083-- @
972−-- main = (S.'toList' . 'asParAhead' $ (,) \<$> s1 \<*> s2) >>= print
1084+-- main = (S.'toList' . 'asyncly' $ (,) \<$> s1 \<*> s2) >>= print
9731085-- @
9741086-- @
9751087-- ThreadId 34: Delay 1
@@ -981,11 +1093,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9811093-- [(1,3),(2,3),(1,4),(2,4)]
9821094-- @
9831095--
984−-- Similalrly 'CoparAhead' as well can run the iterations concurrently and
1096+-- Similalrly 'WAsync' as well can run the iterations concurrently and
9851097-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
9861098--
9871099-- @
988−-- main = (S.'toList' . 'asCoparAhead' $ (,) \<$> s1 \<*> s2) >>= print
1100+-- main = (S.'toList' . 'wAsyncly' $ (,) \<$> s1 \<*> s2) >>= print
9891101-- @
9901102-- @
9911103-- ThreadId 34: Delay 1
@@ -997,21 +1109,6 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
9971109-- [(1,3),(2,3),(1,4),(2,4)]
9981110-- @
9991111
1000−-- $compositionSummary
1001−--
1002−-- The following table summarizes the types for monadic and sum style
1003−-- compositions.
1004−--
1005−-- @
1006−-- +-----+--------------+--------------+
1007−-- | | Serial | Concurrent |
1008−-- +=====+==============+==============+
1009−-- | DFS | 'Stream' | 'ParAhead' |
1010−-- +-----+--------------+--------------+
1011−-- | BFS | 'Costream' | 'CoparAhead' |
1012−-- +-----+--------------+--------------+
1013−-- @
1014−
10151112-- $zipping
10161113--
10171114-- Zipping is a special transformation where the corresponding elements of two
@@ -1023,8 +1120,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10231120
10241121-- $serialzip
10251122--
1026−-- The applicative instance of 'ZipStream' type zips streams serially.
1027−-- 'asZipStream' type combinator can be used to switch to serial applicative
1123+-- The applicative instance of 'ZipSerial' type zips streams serially.
1124+-- 'zipSerially' type combinator can be used to switch to serial applicative
10281125-- zip composition:
10291126--
10301127-- @
@@ -1036,7 +1133,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10361133-- s1 = 'streamly' $ d 1 <> d 2
10371134-- s2 = 'streamly' $ d 3 <> d 4
10381135--
1039−-- main = (S.'toList' . 'asZipStream' $ (,) \<$> s1 \<*> s2) >>= print
1136+-- main = (S.'toList' . 'zipSerially' $ (,) \<$> s1 \<*> s2) >>= print
10401137-- @
10411138--
10421139-- This takes total 10 seconds to zip, which is (1 + 2 + 3 + 4) since
@@ -1052,8 +1149,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10521149
10531150-- $parallelzip
10541151--
1055−-- The applicative instance of 'ZipParallel' type zips streams concurrently.
1056−-- 'asZipParallel' type combinator can be used to switch to parallel applicative
1152+-- The applicative instance of 'ZipAsync' type zips streams concurrently.
1153+-- 'zipAsyncly' type combinator can be used to switch to parallel applicative
10571154-- zip composition:
10581155--
10591156--
@@ -1069,7 +1166,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10691166--
10701167-- main = do
10711168-- hSetBuffering stdout LineBuffering
1072−-- (S.'toList' . 'asZipParallel' $ (,) \<$> s1 \<*> s2) >>= print
1169+-- (S.'toList' . 'zipAsyncly' $ (,) \<$> s1 \<*> s2) >>= print
10731170-- @
10741171--
10751172-- This takes 7 seconds to zip, which is max (1,3) + max (2,4) because 1 and 3
@@ -1093,11 +1190,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
10931190-- choose the desired type of concurrency.
10941191--
10951192-- In the following example the squares of @x@ and @y@ are computed
1096−-- concurrently using the 'parAhead' operation and the square roots of their
1193+-- concurrently using the 'async' operation and the square roots of their
10971194-- sum are computed serially because of the 'streamly' combinator. We can
10981195-- choose different combinators for the monadic processing and the stream
1099−-- generation, to control the concurrency. We can also use the 'asParAhead'
1100−-- combinator instead of explicitly folding with 'parAhead'.
1196+-- generation, to control the concurrency. We can also use the 'asyncly'
1197+-- combinator instead of explicitly folding with 'async'.
11011198--
11021199-- @
11031200-- import "Streamly"
@@ -1106,17 +1203,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11061203--
11071204-- main = do
11081205-- z \<- S.'toList'
1109−-- $ 'asStream' -- Serial monadic processing (sqrt below)
1206+-- $ 'serially' -- Serial monadic processing (sqrt below)
11101207-- $ do
1111−-- x2 \<- 'forEachWith' 'parAhead' [1..100] $ -- Concurrent @"for"@ loop
1208+-- x2 \<- 'forEachWith' 'async' [1..100] $ -- Concurrent @"for"@ loop
11121209-- \\x -> return $ x * x -- body of the loop
1113−-- y2 \<- 'forEachWith' 'parAhead' [1..100] $
1210+-- y2 \<- 'forEachWith' 'async' [1..100] $
11141211-- \\y -> return $ y * y
11151212-- return $ sqrt (x2 + y2)
11161213-- print $ sum z
11171214-- @
11181215--
1119−-- You can see how this directly maps to the imperative style
1216+-- We can see how this directly maps to the imperative style
11201217-- <https://en.wikipedia.org/wiki/OpenMP OpenMP> model, we use combinators
11211218-- and operators instead of the ugly pragmas.
11221219--
@@ -1151,7 +1248,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11511248--
11521249-- data Event = Harm Int | Heal Int | Quit deriving (Show)
11531250--
1154−-- userAction :: MonadIO m => 'StreamT' m Event
1251+-- userAction :: MonadIO m => 'SerialT' m Event
11551252-- userAction = cycle1 $ liftIO askUser
11561253-- where
11571254-- askUser = do
@@ -1161,10 +1258,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
11611258-- "quit" -> return Quit
11621259-- _ -> putStrLn "What?" >> askUser
11631260--
1164−-- acidRain :: MonadIO m => 'StreamT' m Event
1261+-- acidRain :: MonadIO m => 'SerialT' m Event
11651262-- acidRain = cycle1 $ liftIO (threadDelay 1000000) >> return (Harm 1)
11661263--
1167−-- game :: ('MonadParallel' m, MonadState Int m) => 'StreamT' m ()
1264+-- game :: ('MonadAsync' m, MonadState Int m) => 'SerialT' m ()
11681265-- game = do
11691266-- event \<- userAction \`parallel` acidRain
11701267-- case event of
@@ -1356,7 +1453,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
13561453-- When it comes to concurrency, streamly can do everything that the @async@
13571454-- package can do and more. async provides applicative concurrency whereas
13581455-- streamly provides both applicative and monadic concurrency. The
1359−-- 'ZipParallel' type behaves like the applicative instance of async. In
1456+-- 'ZipAsync' type behaves like the applicative instance of async. In
13601457-- comparison to transient streamly has a first class streaming interface and
13611458-- is a monad transformer that can be used universally in any Haskell monad
13621459-- transformer stack. Streamly was in fact originally inspired by the