on master help sign in
Change the nomenclature of streams
c9277a8Harendra Kumar
Changelog.md+20−26
@@ -1,7 +1,7 @@
1## 0.2.0
1## 0.2.0
2
2
3### Breaking changes
3### Breaking changes
4−* Change the semantics of the Semigroup instance for `InterleavedT`, `AsyncT`
4+* Changed the semantics of the Semigroup instance for `InterleavedT`, `AsyncT`
5 and `ParallelT`. The new semantics are as follows:
5 and `ParallelT`. The new semantics are as follows:
6 * For `InterleavedT`, `<>` operation interleaves two streams
6 * For `InterleavedT`, `<>` operation interleaves two streams
7 * For `AsyncT`, `<>` now concurrently merges two streams in a left biased
7 * For `AsyncT`, `<>` now concurrently merges two streams in a left biased
@@ -9,26 +9,26 @@
9 * For `ParallelT`, the `<>` operation now concurrently meges the two streams
9 * For `ParallelT`, the `<>` operation now concurrently meges the two streams
10 in a fairly parallel manner.
10 in a fairly parallel manner.
11
11
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
13 for stream types other than `StreamT`.
13 for stream types other than `StreamT`.
14
14
15* Remove the `Alternative` instance. To adapt to this change replace any usage
15* Remove the `Alternative` instance. To adapt to this change replace any usage
16 of `<|>` with `parallel` and `empty` with `nil`.
16 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
18 using a type combinator or a monomorphic type. This change reduces puzzling
18 using a type combinator or a monomorphic type. This change reduces puzzling
19 type errors for beginners. It includes the following two changes:
19 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`
21 instead of a polymorphic type. This makes sure that the stream type is
21 instead of a polymorphic type. This makes sure that the stream type is
22 always fixed at all exits.
22 always fixed at all exits.
23 * Change the type combinators (e.g. `parallely`) to only fix the argument
23 * Change the type combinators (e.g. `parallely`) to only fix the argument
24 stream type and the output stream type remains polymorphic.
24 stream type and the output stream type remains polymorphic.
25−
26 Stream types may have to be changed or type combinators may have to be added
25 Stream types may have to be changed or type combinators may have to be added
27 or removed to adapt to this change.
26 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`.
31* Change the type of `foldrM` to make it consistent with `foldrM` in base.
27* 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.
32* Remove the `MonadError` instance as it was not working correctly for
32* Remove the `MonadError` instance as it was not working correctly for
33 parallel compositions. Use `MonadThrow` instead for error propagation.
33 parallel compositions. Use `MonadThrow` instead for error propagation.
34* Remove Num/Fractional/Floating instances as they are not very useful. Use
34* Remove Num/Fractional/Floating instances as they are not very useful. Use
@@ -36,26 +36,21 @@
36
36
37### Deprecations
37### Deprecations
38* Deprecate and rename the following symbols:
38* Deprecate and rename the following symbols:
39− * `MonadAsync` to `MonadParallel`
40 * `Streaming` to `IsStream`
39 * `Streaming` to `IsStream`
41 * `runStreaming` to `runStream`
40 * `runStreaming` to `runStream`
41+ * `StreamT` to `SerialT`
42− * `InterleavedT` to `CostreamT`
42+ * `InterleavedT` to `WSerialT`
43− * `AsyncT` to `ParAheadT`
43+ * `ZipStream` to `ZipSerialM`
44− * `ZipAsync` to `ZipParallelM`
44+ * `ZipAsync` to `ZipAsyncM`
45− * `serially` to `asStream`
46− * `interleaving` to `asCostream`
45+ * `interleaving` to `wSerially`
47− * `asyncly` to `asParAhead`
48− * `parallely` to `asParallel`
49− * `zipping` to `asZipStream`
46+ * `zipping` to `zipSerially`
50− * `zippingAsync` to `asZipParallel`
47+ * `zippingAsync` to `zipAsyncly`
51− * `<=>` to `cosplice`
48+ * `<=>` to `wSerial`
52− * `<|` to `parAhead`
49+ * `<|` to `async`
53 * `each` to `fromFoldable`
50 * `each` to `fromFoldable`
54 * `scan` to `scanx`
51 * `scan` to `scanx`
55 * `foldl` to `foldx`
52 * `foldl` to `foldx`
56 * `foldlM` to `foldxM`
53 * `foldlM` to `foldxM`
57− * `zipAsyncWith` to `zipParallelWith`
58− * `zipAsyncWithM` to `zipParallelWithM`
59* Deprecate the following symbols for future removal:
54* Deprecate the following symbols for future removal:
60 * `runStreamT`
55 * `runStreamT`
61 * `runInterleavedT`
56 * `runInterleavedT`
@@ -72,11 +67,10 @@
72 * `scanl'` strict left scan
67 * `scanl'` strict left scan
73 * `foldl'` strict left fold
68 * `foldl'` strict left fold
74 * `foldlM'` strict left fold with a monadic fold function
69 * `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
76 * `parallel` run two streams in parallel (replaces `<|>`)
72 * `parallel` run two streams in parallel (replaces `<|>`)
77− * `CoparAhead` stream type for BFS version of ahead parallel composition
73+ * `WAsyncT` stream type for BFS version of `AsyncT` composition
78− * `coparAhead` ahead parallel composition of two streams
79− * `asCoparAhead` type combinator for CoparAhead stream type
80* Add simpler stream types that are specialized to the IO monad
74* Add simpler stream types that are specialized to the IO monad
81
75
82## 0.1.2
76## 0.1.2
README.md+27−18
@@ -32,8 +32,8 @@ the functionality of list transformer libraries like `pipes` or
32[list-t](https://hackage.haskell.org/package/list-t) and also the logic
32[list-t](https://hackage.haskell.org/package/list-t) and also the logic
33programming library [logict](https://hackage.haskell.org/package/logict). On
33programming library [logict](https://hackage.haskell.org/package/logict). On
34the concurrency side, it subsumes the functionality of the
34the concurrency side, it subsumes the functionality of the
35−[async](https://hackage.haskell.org/package/async) package. Because it streams
35+[async](https://hackage.haskell.org/package/async) package. Because it supports
36−and supports concurrency we can write FRP applications similar in concept to
36+streaming with concurrency we can write FRP applications similar in concept to
37[Yampa](https://hackage.haskell.org/package/Yampa) or
37[Yampa](https://hackage.haskell.org/package/Yampa) or
38[reflex](https://hackage.haskell.org/package/reflex). To understand the
38[reflex](https://hackage.haskell.org/package/reflex). To understand the
39streaming library ecosystem and where streamly fits in you may want to read
39streaming library ecosystem and where streamly fits in you may want to read
@@ -57,7 +57,7 @@ Why use streamly?
57 [streaming-benchmarks](https://github.com/composewell/streaming-benchmarks)
57 [streaming-benchmarks](https://github.com/composewell/streaming-benchmarks)
58 for a comparison of popular streaming libraries on micro-benchmarks.
58 for a comparison of popular streaming libraries on micro-benchmarks.
59
59
60− For more information:
60+ For more information, see:
61
61
62 * [Streamly.Tutorial](https://hackage.haskell.org/package/streamly/docs/Streamly-Tutorial.html) module in the haddock documentation for a detailed introduction
62 * [Streamly.Tutorial](https://hackage.haskell.org/package/streamly/docs/Streamly-Tutorial.html) module in the haddock documentation for a detailed introduction
63 * [examples](https://github.com/composewell/streamly/tree/master/examples) directory in the package for some simple practical examples
63 * [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`
68composes stream data instead of stream processors (functions). A stream is
68composes stream data instead of stream processors (functions). A stream is
69just like a list and is explicitly passed around to functions that process the
69just like a list and is explicitly passed around to functions that process the
70stream. Therefore, no special operator is needed to join stages in a streaming
70stream. Therefore, no special operator is needed to join stages in a streaming
71−pipeline, just a forward (`$`) or reverse (`&`) function application operator
71+pipeline, just the standard forward (`$`) or reverse (`&`) function application
72−is enough. Combinators are provided in `Streamly.Prelude` to transform or fold
72+operator is enough. Combinators are provided in `Streamly.Prelude` to
73−streams.
73+transform or fold streams.
74
74
75```haskell
75```haskell
76import Streamly
76import Streamly
@@ -90,8 +90,8 @@ main = runStream $
90
90
91Semigroup and Monoid instances can be used to fold streams serially or
91Semigroup and Monoid instances can be used to fold streams serially or
92concurrently. In the following example we are composing ten actions in the
92concurrently. 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
93+stream each with a delay of 1 to 10 seconds, respectively. Since all the
94−concurrent we see one output printed every second:
94+actions are concurrent we see one output printed every second:
95
95
96``` haskell
96``` haskell
97import Streamly
97import Streamly
@@ -102,7 +102,9 @@ main = S.toList $ parallely $ foldMap delay [1..10]
102 where delay n = S.once $ threadDelay (n * 1000000) >> print n
102 where delay n = S.once $ threadDelay (n * 1000000) >> print n
103```
103```
104
104
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:
106
108
107``` haskell
109``` haskell
108import Streamly
110import Streamly
@@ -160,29 +162,36 @@ main = runStream loops
160
162
161## Concurrent Nested Loops
163## Concurrent Nested Loops
162
164
163−To run the above code with demand-driven concurrency i.e. each iteration in the
165+To run the above code with demand-driven depth first concurrency i.e. each
164−loops can run concurrently depending on the consumer rate:
166+iteration in the loops can run concurrently depending on the consumer rate:
165
167
166``` haskell
168``` haskell
167−main = runStream $ coparallely $ loops
169+main = runStream $ asyncly $ loops
168```
170```
169
171
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:
171
179
172``` haskell
180``` haskell
173main = runStream $ parallely $ loops
181main = runStream $ parallely $ loops
174```
182```
175
183
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):
177
186
178``` haskell
187``` haskell
179−main = runStream $ costreamly $ loops
188+main = runStream $ wSerially $ loops
180```
189```
181
190
182## Magical Concurrency
191## Magical Concurrency
183
192
184Streams can perform semigroup (<>) and monadic bind (>>=) operations
193Streams 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,
186to concurrently generate squares of a stream of numbers and then concurrently
195to concurrently generate squares of a stream of numbers and then concurrently
187sum the square roots of all combinations of two streams:
196sum the square roots of all combinations of two streams:
188
197
@@ -191,7 +200,7 @@ import Streamly
191import qualified Streamly.Prelude as S
200import qualified Streamly.Prelude as S
192
201
193main = do
202main = do
194− s <- S.sum $ coparallely $ do
203+ s <- S.sum $ asyncly $ do
195 -- Each square is performed concurrently, (<>) is concurrent
204 -- Each square is performed concurrently, (<>) is concurrent
196 x2 <- foldMap (\x -> return $ x * x) [1..100]
205 x2 <- foldMap (\x -> return $ x * x) [1..100]
197 y2 <- foldMap (\y -> return $ x * x) [1..100]
206 y2 <- foldMap (\y -> return $ x * x) [1..100]
@@ -207,7 +216,7 @@ example, to concurrently list the contents of a directory tree recursively:
207import Path.IO (listDir, getCurrentDir)
216import Path.IO (listDir, getCurrentDir)
208import Streamly
217import Streamly
209
218
210−main = runStream $ coparallely $ getCurrentDir >>= readdir
219+main = runStream $ asyncly $ getCurrentDir >>= readdir
211 where readdir d = do
220 where readdir d = do
212 (dirs, files) <- S.once $ listDir d
221 (dirs, files) <- S.once $ listDir d
213 S.once $ mapM_ putStrLn $ map show files
222 S.once $ mapM_ putStrLn $ map show files
src/Streamly.hs+58−66
@@ -15,18 +15,18 @@
15-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
15-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
16-- appending streams of arbitrary length is scalable and inexpensive.
16-- appending streams of arbitrary length is scalable and inexpensive.
17--
17--
18−-- The basic stream type is 'Stream', it represents a sequence of IO actions,
18+-- The basic stream type is 'Serial', it represents a sequence of IO actions,
19−-- and is a 'Monad'. The type 'StreamT' is a monad transformer that can
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 'Stream' is
20+-- represent a sequence of actions in an arbitrary monad. The type 'Serial' is
21−-- in fact a synonym for @StreamT IO@. There are a few more types similar to
21+-- in fact a synonym for @SerialT IO@. There are a few more types similar to
22−-- 'StreamT', all of them represent a stream and differ only in the
22+-- 'SerialT', all of them represent a stream and differ only in the
23−-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Stream'
23+-- 'Semigroup', 'Applicative' and 'Monad' compositions of the stream. 'Serial'
24−-- and 'Costream' types compose serially whereas 'ParAhead' and 'CoparAhead'
24+-- and 'WSerial' types compose serially whereas 'Async' and 'WAsync'
25-- types compose concurrently. All these types can be freely inter-converted
25-- types compose concurrently. All these types can be freely inter-converted
26-- using type combinators without any cost. You can freely switch to any type
26-- using type combinators without any cost. You can freely switch to any type
27-- of composition at any point in the program. When no type annotation or
27-- of composition at any point in the program. When no type annotation or
28-- explicit stream type combinators are used, the default stream type is
28-- explicit stream type combinators are used, the default stream type is
29−-- inferred as 'Stream'.
29+-- inferred as 'Serial'.
30--
30--
31-- Here is a simple console echo program example:
31-- Here is a simple console echo program example:
32--
32--
@@ -57,60 +57,60 @@
57
57
58module Streamly
58module Streamly
59 (
59 (
60− MonadParallel
60+ MonadAsync
61
61
62 -- * Stream transformers
62 -- * Stream transformers
63 -- ** Serial Streams
63 -- ** Serial Streams
64 -- $serial
64 -- $serial
65− , StreamT
65+ , SerialT
66− , CostreamT
66+ , WSerialT
67
67
68 -- ** Parallel Streams
68 -- ** Parallel Streams
69− -- $parAhead
69+ -- $async
70− , ParAheadT
70+ , AsyncT
71− , CoparAheadT
71+ , WAsyncT
72 , ParallelT
72 , ParallelT
73
73
74 -- ** Zipping Streams
74 -- ** Zipping Streams
75 -- $zipping
75 -- $zipping
76− , ZipStreamM
76+ , ZipSerialM
77− , ZipParallelM
77+ , ZipAsyncM
78
78
79 -- * Polymorphic Sum Operations
79 -- * Polymorphic Sum Operations
80 -- $sum
80 -- $sum
81− , splice
81+ , serial
82− , cosplice
82+ , wSerial
83− , parAhead
83+ , async
84− , coparAhead
84+ , wAsync
85 , parallel
85 , parallel
86
86
87 -- * Stream Type Adapters
87 -- * Stream Type Adapters
88 -- $adapters
88 -- $adapters
89 , IsStream
89 , IsStream
90
90
91− , asStream
91+ , serially
92− , asCostream
92+ , wSerially
93− , asParAhead
93+ , asyncly
94− , asCoparAhead
94+ , wAsyncly
95− , asParallel
95+ , parallely
96− , asZipStream
96+ , zipSerially
97− , asZipParallel
97+ , zipAsyncly
98 , adapt
98 , adapt
99
99
100 -- * IO Streams
100 -- * IO Streams
101− , Stream
101+ , Serial
102− , Costream
102+ , WSerial
103− , ParAhead
103+ , Async
104− , CoparAhead
104+ , WAsync
105 , Parallel
105 , Parallel
106− , ZipStream
106+ , ZipSerial
107− , ZipParallel
107+ , ZipAsync
108
108
109 -- * Running Streams
109 -- * Running Streams
110 , runStream
110 , runStream
111
111
112 -- * Transformation
112 -- * Transformation
113− , async
113+ , mkAsync
114
114
115 -- * Polymorphic Fold Utilities
115 -- * Polymorphic Fold Utilities
116 -- $foldutils
116 -- $foldutils
@@ -121,22 +121,18 @@ module Streamly
121 -- * Re-exports
121 -- * Re-exports
122 , Semigroup (..)
122 , Semigroup (..)
123 -- * Deprecated
123 -- * Deprecated
124− , MonadAsync
125 , Streaming
124 , Streaming
126 , runStreaming
125 , runStreaming
127 , runStreamT
126 , runStreamT
128 , runInterleavedT
127 , runInterleavedT
129− , runParallelT
130− , runZipAsync
131 , runAsyncT
128 , runAsyncT
129+ , runParallelT
132 , runZipStream
130 , runZipStream
131+ , runZipAsync
132+ , StreamT
133 , InterleavedT
133 , InterleavedT
134− , AsyncT
134+ , ZipStream
135− , ZipAsync
136− , serially
137 , interleaving
135 , interleaving
138− , asyncly
139− , parallely
140 , zipping
136 , zipping
141 , zippingAsync
137 , zippingAsync
142 , (<=>)
138 , (<=>)
@@ -150,28 +146,24 @@ import Data.Semigroup (Semigroup(..))
150-- $serial
146-- $serial
151--
147--
152-- Serial streams compose serially or non-concurrently. In a composed stream,
148-- 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.
149+-- each action is executed only after the prvious action has finished. The two
154−-- The two serial stream types 'StreamT' and 'CostreamT' differ in how they
150+-- serial stream types 'SerialT' and 'WSerialT' differ in how they traverse the
155−-- merge streams together in a 'Semigroup' or 'Monad' composition. As these
151+-- streams in a 'Semigroup' or 'Monad' composition.
156−-- streams are serial, the sequence of items in a composed stream can be solely
152+
157−-- determined by the position of elements in the consituent streams.
153+-- $async
158−
159−-- $parAhead
160−--
154+--
161−-- Parallel ahead streams compose in an ahead parallel manner. In a composed stream, at
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
162−-- any point of time more than one stream can run concurrently and yield
157+-- more than one stream can run concurrently and yield elements. The elements
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
158+-- are yielded by the composed stream as they are generated by the constituent
168−-- generated by the constituent streams on a first come first serve basis.
159+-- streams on a first come first serve basis. Therefore, on each run the
169−-- Therefore, on each run the stream may yield elements in a different sequence
160+-- stream may yield elements in a different sequence depending on the delays
170−-- depending on the delays introduced by scheduling.
161+-- introduced by scheduling. The two async types 'AsyncT' and 'WAsyncT' differ
162+-- in how they traverse streams in 'Semigroup' or 'Monad' compositions.
171
163
172-- $zipping
164-- $zipping
173--
165--
174−-- 'ZipStreamM' and 'ZipParallelM', provide 'Applicative' instances for zipping the
166+-- 'ZipSerialM' and 'ZipAsyncM', provide 'Applicative' instances for zipping the
175-- corresponding elements of two streams together. Note that these types are
167-- corresponding elements of two streams together. Note that these types are
176-- not monads.
168-- not monads.
177
169
@@ -189,11 +181,11 @@ import Data.Semigroup (Semigroup(..))
189-- one stream type to another. It is not used directly, instead the type
181-- one stream type to another. It is not used directly, instead the type
190-- combinators provided below are used for conversions.
182-- combinators provided below are used for conversions.
191--
183--
192−-- To adapt from one monomorphic type (e.g. 'parAheadT') to another monomorphic
184+-- To adapt from one monomorphic type (e.g. 'AsyncT') to another monomorphic
193−-- type (e.g. 'StreamT') use the 'adapt' combinator. To give a polymorphic code
185+-- type (e.g. 'SerialT') use the 'adapt' combinator. To give a polymorphic code
194-- a specific interpretation or to adapt a specific type to a polymorphic type
186-- 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
187+-- use the type specific combinators e.g. 'asyncly' or 'wSerially'. You
196−-- cannot adapt polymorphic code to polymorphic code, as it would not know
188+-- cannot adapt polymorphic code to polymorphic code, as the compiler would not know
197-- which specific type you are converting from or to. If you see a an
189-- which specific type you are converting from or to. If you see a an
198-- @ambiguous type variable@ error then most likely you are using 'adapt'
190-- @ambiguous type variable@ error then most likely you are using 'adapt'
199-- unnecessarily on polymorphic code.
191-- unnecessarily on polymorphic code.
@@ -202,5 +194,5 @@ import Data.Semigroup (Semigroup(..))
202-- $foldutils
194-- $foldutils
203--
195--
204-- These are variants of standard 'Foldable' fold functions that use a
196-- 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
206-- container of streams.
198-- container of streams.
src/Streamly/Core.hs+40−46
@@ -20,8 +20,7 @@
20--
20--
21module Streamly.Core
21module Streamly.Core
22 (
22 (
23− MonadParallel
24− , MonadAsync -- deprecated
23+ MonadAsync
25
24
26 -- * Streams
25 -- * Streams
27 , Stream (..)
26 , Stream (..)
@@ -35,10 +34,10 @@ module Streamly.Core
35 , nil
34 , nil
36
35
37 -- * Semigroup Style Composition
36 -- * Semigroup Style Composition
38− , splice
37+ , serial
39− , cosplice
38+ , wSerial
40− , parAhead
39+ , async
41− , coparAhead
40+ , wAsync
42 , parallel
41 , parallel
43
42
44 -- * Alternative
43 -- * Alternative
@@ -46,7 +45,7 @@ module Streamly.Core
46
45
47 -- * zip
46 -- * zip
48 , zipWith
47 , zipWith
49− , zipParallelWith
48+ , zipAsyncWith
50
49
51 -- * Transformers
50 -- * Transformers
52 , withLocal
51 , withLocal
@@ -234,8 +233,8 @@ repeat a = let x = cons a x in x
234
233
235-- | Concatenates two streams sequentially i.e. the first stream is
234-- | Concatenates two streams sequentially i.e. the first stream is
236-- exhausted completely before yielding any element from the second stream.
235-- exhausted completely before yielding any element from the second stream.
237−splice :: Stream m a -> Stream m a -> Stream m a
236+serial :: Stream m a -> Stream m a -> Stream m a
238−splice m1 m2 = go m1
237+serial m1 m2 = go m1
239 where
238 where
240 go (Stream m) = Stream $ \_ stp sng yld ->
239 go (Stream m) = Stream $ \_ stp sng yld ->
241 let stop = (runStream m2) Nothing stp sng yld
240 let stop = (runStream m2) Nothing stp sng yld
@@ -244,7 +243,7 @@ splice m1 m2 = go m1
244 in m Nothing stop single yield
243 in m Nothing stop single yield
245
244
246instance Semigroup (Stream m a) where
245instance Semigroup (Stream m a) where
247− (<>) = splice
246+ (<>) = serial
248
247
249------------------------------------------------------------------------------
248------------------------------------------------------------------------------
250-- Monoid
249-- Monoid
@@ -258,11 +257,11 @@ instance Monoid (Stream m a) where
258-- Interleave
257-- Interleave
259------------------------------------------------------------------------------
258------------------------------------------------------------------------------
260
259
261−cosplice :: Stream m a -> Stream m a -> Stream m a
260+wSerial :: Stream m a -> Stream m a -> Stream m a
262−cosplice m1 m2 = Stream $ \_ stp sng yld -> do
261+wSerial m1 m2 = Stream $ \_ stp sng yld -> do
263 let stop = (runStream m2) Nothing stp sng yld
262 let stop = (runStream m2) Nothing stp sng yld
264 single a = yld a m2
263 single a = yld a m2
265− yield a r = yld a (cosplice m2 r)
264+ yield a r = yld a (wSerial m2 r)
266 (runStream m1) Nothing stop single yield
265 (runStream m1) Nothing stop single yield
267
266
268------------------------------------------------------------------------------
267------------------------------------------------------------------------------
@@ -271,15 +270,10 @@ cosplice m1 m2 = Stream $ \_ stp sng yld -> do
271
270
272-- | A monad that can perform concurrent or parallel IO operations. Streams
271-- | A monad that can perform concurrent or parallel IO operations. Streams
273-- that can be composed concurrently require the underlying monad to be
272-- that can be composed concurrently require the underlying monad to be
274−-- 'MonadParallel'.
273+-- 'MonadAsync'.
275--
274--
276−-- @since 0.2.0
277−type MonadParallel m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
278−
279−-- |
280-- @since 0.1.0
275-- @since 0.1.0
281−{-# DEPRECATED MonadAsync "Please use MonadParallel instead." #-}
276+type MonadAsync m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
282−type MonadAsync m = MonadParallel m
283
277
284-- Stolen from the async package. The perf improvement is modest, 2% on a
278-- Stolen from the async package. The perf improvement is modest, 2% on a
285-- thread heavy benchmark (parallel composition using noop computations).
279-- thread heavy benchmark (parallel composition using noop computations).
@@ -453,7 +447,7 @@ handleChildException sv e = do
453 send sv (ChildStop tid (Just e))
447 send sv (ChildStop tid (Just e))
454
448
455{-# NOINLINE pushWorker #-}
449{-# NOINLINE pushWorker #-}
456−pushWorker :: MonadParallel m => SVar m a -> m ()
450+pushWorker :: MonadAsync m => SVar m a -> m ()
457pushWorker sv = do
451pushWorker sv = do
458 liftIO $ atomicModifyIORefCAS_ (activeWorkers sv) $ \n -> n + 1
452 liftIO $ atomicModifyIORefCAS_ (activeWorkers sv) $ \n -> n + 1
459 doFork (runqueue sv) (handleChildException sv) >>= addThread sv
453 doFork (runqueue sv) (handleChildException sv) >>= addThread sv
@@ -464,7 +458,7 @@ pushWorker sv = do
464-- runningThreads. Alternatively, we can use a CreateThread event to avoid
458-- runningThreads. Alternatively, we can use a CreateThread event to avoid
465-- using a CAS based modification.
459-- using a CAS based modification.
466{-# NOINLINE pushWorkerPar #-}
460{-# NOINLINE pushWorkerPar #-}
467−pushWorkerPar :: MonadParallel m => SVar m a -> Stream m a -> m ()
461+pushWorkerPar :: MonadAsync m => SVar m a -> Stream m a -> m ()
468pushWorkerPar sv m =
462pushWorkerPar sv m =
469 doFork (runOne sv m) (handleChildException sv) >>= modifyThread sv
463 doFork (runOne sv m) (handleChildException sv) >>= modifyThread sv
470
464
@@ -473,7 +467,7 @@ pushWorkerPar sv m =
473-- block or make it go away entirely, depending on the number of workers and
467-- block or make it go away entirely, depending on the number of workers and
474-- the type of the queue.
468-- the type of the queue.
475{-# INLINE sendWorkerWait #-}
469{-# INLINE sendWorkerWait #-}
476−sendWorkerWait :: MonadParallel m => SVar m a -> m ()
470+sendWorkerWait :: MonadAsync m => SVar m a -> m ()
477sendWorkerWait sv = do
471sendWorkerWait sv = do
478 -- When there is no output seen we dispatch more workers to help out if
472 -- When there is no output seen we dispatch more workers to help out if
479 -- there is work pending in the work queue. But we wait a little while
473 -- there is work pending in the work queue. But we wait a little while
@@ -497,7 +491,7 @@ sendWorkerWait sv = do
497
491
498-- | Pull a stream from an SVar.
492-- | Pull a stream from an SVar.
499{-# NOINLINE fromStreamVar #-}
493{-# NOINLINE fromStreamVar #-}
500−fromStreamVar :: MonadParallel m => SVar m a -> Stream m a
494+fromStreamVar :: MonadAsync m => SVar m a -> Stream m a
501fromStreamVar sv = Stream $ \_ stp sng yld -> do
495fromStreamVar sv = Stream $ \_ stp sng yld -> do
502 let SVarStyle _ sched = svarStyle sv
496 let SVarStyle _ sched = svarStyle sv
503 if sched == Par
497 if sched == Par
@@ -607,7 +601,7 @@ getParSVar style = do
607 in return sv
601 in return sv
608
602
609-- | Create a new empty SVar.
603-- | Create a new empty SVar.
610−newEmptySVar :: MonadParallel m => SVarStyle -> m (SVar m a)
604+newEmptySVar :: MonadAsync m => SVarStyle -> m (SVar m a)
611newEmptySVar style = do
605newEmptySVar style = do
612 liftIO $
606 liftIO $
613 case style of
607 case style of
@@ -616,7 +610,7 @@ newEmptySVar style = do
616 SVarStyle _ Par -> getParSVar style
610 SVarStyle _ Par -> getParSVar style
617
611
618-- | Create a new SVar and enqueue one stream computation on it.
612-- | 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)
620newStreamVar1 style m = do
614newStreamVar1 style m = do
621 sv <- newEmptySVar style
615 sv <- newEmptySVar style
622 -- Note: We must have all the work on the queue before sending the
616 -- Note: We must have all the work on the queue before sending the
@@ -627,7 +621,7 @@ newStreamVar1 style m = do
627 return sv
621 return sv
628
622
629-- | Create a new SVar and enqueue two stream computations on it.
623-- | Create a new SVar and enqueue two stream computations on it.
630−newStreamVar2 :: MonadParallel m
624+newStreamVar2 :: MonadAsync m
631 => SVarStyle -> Stream m a -> Stream m a -> m (SVar m a)
625 => SVarStyle -> Stream m a -> Stream m a -> m (SVar m a)
632newStreamVar2 style m1 m2 = do
626newStreamVar2 style m1 m2 = do
633 -- Note: We must have all the work on the queue before sending the
627 -- Note: We must have all the work on the queue before sending the
@@ -649,7 +643,7 @@ newStreamVar2 style m1 m2 = do
649
643
650-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
644-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
651-- be read back from the SVar using 'fromSVar'.
645-- 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 ()
653toStreamVar sv m = do
647toStreamVar sv m = do
654 liftIO $ (enqueue sv) m
648 liftIO $ (enqueue sv) m
655 done <- allThreadsDone sv
649 done <- allThreadsDone sv
@@ -678,7 +672,7 @@ toStreamVar sv m = do
678--
672--
679-- TBD Note 2: We may want to run computations at the lower level of the
673-- TBD Note 2: We may want to run computations at the lower level of the
680-- composition tree serially even when they are composed using a parallel
674-- 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
682-- place of 'coParAhead'. If we find that an SVar immediately above a computation
676-- place of 'coParAhead'. If we find that an SVar immediately above a computation
683-- gets drained empty we can switch to parallelizing the computation. For that
677-- gets drained empty we can switch to parallelizing the computation. For that
684-- we can use a state flag to fork the rest of the computation at any point of
678-- 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
714-- Cases when we need to switch to a new SVar:
708-- Cases when we need to switch to a new SVar:
715--
709--
716-- * (x `parallel` y) `parallel` (t `parallel` u) -- all of them get scheduled on the same SVar
710-- * (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
718-- because of the scheduling policy change.
712-- 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
720-- 'Parallel', we create a new SVar at the transitioning bind.
714-- 'Parallel', we create a new SVar at the transitioning bind.
721-- * When the stream is switching from disjunctive composition to conjunctive
715-- * When the stream is switching from disjunctive composition to conjunctive
722-- composition and vice-versa we create a new SVar to isolate the scheduling
716-- composition and vice-versa we create a new SVar to isolate the scheduling
723-- of the two.
717-- of the two.
724--
718--
725{-# INLINE joinStreamVar2 #-}
719{-# INLINE joinStreamVar2 #-}
726−joinStreamVar2 :: MonadParallel m
720+joinStreamVar2 :: MonadAsync m
727 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
721 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
728joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
722joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
729 case svr of
723 case svr of
@@ -738,7 +732,7 @@ joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
738 (runStream ma) svr stp sng yld
732 (runStream ma) svr stp sng yld
739
733
740{-# INLINE joinStreamVarPar #-}
734{-# INLINE joinStreamVarPar #-}
741−joinStreamVarPar :: MonadParallel m
735+joinStreamVarPar :: MonadAsync m
742 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
736 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
743joinStreamVarPar style m1 m2 = Stream $ \svr stp sng yld ->
737joinStreamVarPar style m1 m2 = Stream $ \svr stp sng yld ->
744 case svr of
738 case svr of
@@ -754,16 +748,16 @@ joinStreamVarPar style m1 m2 = Stream $ \svr stp sng yld ->
754-- Semigroup and Monoid style compositions for parallel actions
748-- Semigroup and Monoid style compositions for parallel actions
755------------------------------------------------------------------------------
749------------------------------------------------------------------------------
756
750
757−{-# INLINE parAhead #-}
751+{-# INLINE async #-}
758−parAhead :: MonadParallel m => Stream m a -> Stream m a -> Stream m a
752+async :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
759−parAhead = joinStreamVar2 (SVarStyle Disjunction LIFO)
753+async = joinStreamVar2 (SVarStyle Disjunction LIFO)
760
754
761−{-# INLINE coparAhead #-}
755+{-# INLINE wAsync #-}
762−coparAhead :: MonadParallel m => Stream m a -> Stream m a -> Stream m a
756+wAsync :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
763−coparAhead = joinStreamVar2 (SVarStyle Disjunction FIFO)
757+wAsync = joinStreamVar2 (SVarStyle Disjunction FIFO)
764
758
765{-# INLINE parallel #-}
759{-# 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
767parallel = joinStreamVarPar (SVarStyle Disjunction Par)
761parallel = joinStreamVarPar (SVarStyle Disjunction Par)
768
762
769-------------------------------------------------------------------------------
763-------------------------------------------------------------------------------
@@ -801,15 +795,15 @@ zipWith f m1 m2 = go m1 m2
801 yield1 a ra = merge a ra
795 yield1 a ra = merge a ra
802 (runStream mx) Nothing stp single1 yield1
796 (runStream mx) Nothing stp single1 yield1
803
797
804−async :: MonadParallel m => Stream m a -> m (Stream m a)
798+mkAsync :: MonadAsync m => Stream m a -> m (Stream m a)
805−async m = newStreamVar1 (SVarStyle Disjunction LIFO) m
799+mkAsync m = newStreamVar1 (SVarStyle Disjunction LIFO) m
806 >>= return . fromStreamVar
800 >>= return . fromStreamVar
807
801
808−zipParallelWith :: MonadParallel m
802+zipAsyncWith :: MonadAsync m
809 => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
803 => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
810−zipParallelWith f m1 m2 = Stream $ \_ stp sng yld -> do
804+zipAsyncWith f m1 m2 = Stream $ \_ stp sng yld -> do
811− ma <- async m1
805+ ma <- mkAsync m1
812− mb <- async m2
806+ mb <- mkAsync m2
813 (runStream (zipWith f ma mb)) Nothing stp sng yld
807 (runStream (zipWith f ma mb)) Nothing stp sng yld
814
808
815-------------------------------------------------------------------------------
809-------------------------------------------------------------------------------
src/Streamly/Prelude.hs+36−52
@@ -26,7 +26,7 @@
26-- provided for convenience and for consistency with other pure APIs in the
26-- provided for convenience and for consistency with other pure APIs in the
27-- @base@ package.
27-- @base@ package.
28--
28--
29−-- Deconstruction and folds accept a 'StreamT' type instead of a polymorphic
29+-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
30-- type to ensure that streams always have a concrete monomorphic type by
30-- type to ensure that streams always have a concrete monomorphic type by
31-- default, reducing type errors. In case you want to use any other type of
31-- default, reducing type errors. In case you want to use any other type of
32-- stream you can use one of the type combinators provided in the "Streamly"
32-- stream you can use one of the type combinators provided in the "Streamly"
@@ -106,8 +106,8 @@ module Streamly.Prelude
106 -- * Zipping
106 -- * Zipping
107 , zipWith
107 , zipWith
108 , zipWithM
108 , zipWithM
109− , zipParallelWith
109+ , zipAsyncWith
110− , zipParallelWithM
110+ , zipAsyncWithM
111
111
112 -- * IO
112 -- * IO
113 , fromHandle
113 , fromHandle
@@ -118,8 +118,6 @@ module Streamly.Prelude
118 , scan
118 , scan
119 , foldl
119 , foldl
120 , foldlM
120 , foldlM
121− , zipAsyncWith
122− , zipAsyncWithM
123 )
121 )
124where
122where
125
123
@@ -260,7 +258,7 @@ fromHandle h = fromStream go
260-- @
258-- @
261--
259--
262-- @since 0.1.0
260-- @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
264foldr step acc m = go (toStream m)
262foldr step acc m = go (toStream m)
265 where
263 where
266 go m1 =
264 go m1 =
@@ -279,7 +277,7 @@ foldr step acc m = go (toStream m)
279--
277--
280-- @since 0.2.0
278-- @since 0.2.0
281{-# INLINE foldrM #-}
279{-# 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
283foldrM step acc m = go (toStream m)
281foldrM step acc m = go (toStream m)
284 where
282 where
285 go m1 =
283 go m1 =
@@ -328,7 +326,7 @@ scanl' step begin m = scanx step begin id m
328--
326--
329-- @since 0.2.0
327-- @since 0.2.0
330{-# INLINE foldx #-}
328{-# 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
332foldx step begin done m = get $ go (toStream m) begin
330foldx step begin done m = get $ go (toStream m) begin
333 where
331 where
334 {-# NOINLINE get #-}
332 {-# NOINLINE get #-}
@@ -351,21 +349,21 @@ foldx step begin done m = get $ go (toStream m) begin
351-- |
349-- |
352-- @since 0.1.0
350-- @since 0.1.0
353{-# DEPRECATED foldl "Please use foldx instead." #-}
351{-# 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
355foldl = foldx
353foldl = foldx
356
354
357-- | Strict left associative fold.
355-- | Strict left associative fold.
358--
356--
359-- @since 0.2.0
357-- @since 0.2.0
360{-# INLINE foldl' #-}
358{-# 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
362foldl' step begin m = foldx step begin id m
360foldl' step begin m = foldx step begin id m
363
361
364-- XXX replace the recursive "go" with explicit continuations.
362-- XXX replace the recursive "go" with explicit continuations.
365-- | Like 'foldx', but with a monadic step function.
363-- | Like 'foldx', but with a monadic step function.
366--
364--
367-- @since 0.2.0
365-- @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
369foldxM step begin done m = go begin (toStream m)
367foldxM step begin done m = go begin (toStream m)
370 where
368 where
371 go !acc m1 =
369 go !acc m1 =
@@ -377,13 +375,13 @@ foldxM step begin done m = go begin (toStream m)
377-- |
375-- |
378-- @since 0.1.0
376-- @since 0.1.0
379{-# DEPRECATED foldlM "Please use foldxM instead." #-}
377{-# 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
381foldlM = foldxM
379foldlM = foldxM
382
380
383-- | Like 'foldl'' but with a monadic step function.
381-- | Like 'foldl'' but with a monadic step function.
384--
382--
385-- @since 0.2.0
383-- @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
387foldlM' step begin m = foldxM step (return begin) return m
385foldlM' step begin m = foldxM step (return begin) return m
388
386
389-- | Decompose a stream into its head and tail. If the stream is empty, returns
387-- | 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
391-- the head of the stream and 'ma' its tail.
389-- the head of the stream and 'ma' its tail.
392--
390--
393-- @since 0.1.0
391-- @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))
395uncons m =
393uncons m =
396 let stop = return Nothing
394 let stop = return Nothing
397 single a = return (Just (a, nil))
395 single a = return (Just (a, nil))
@@ -401,7 +399,7 @@ uncons m =
401-- | Write a stream of Strings to an IO Handle.
399-- | Write a stream of Strings to an IO Handle.
402--
400--
403-- @since 0.1.0
401-- @since 0.1.0
404−toHandle :: MonadIO m => IO.Handle -> StreamT m String -> m ()
402+toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
405toHandle h m = go (toStream m)
403toHandle h m = go (toStream m)
406 where
404 where
407 go m1 =
405 go m1 =
@@ -418,7 +416,7 @@ toHandle h m = go (toStream m)
418--
416--
419-- @since 0.1.0
417-- @since 0.1.0
420{-# INLINABLE toList #-}
418{-# INLINABLE toList #-}
421−toList :: Monad m => StreamT m a -> m [a]
419+toList :: Monad m => SerialT m a -> m [a]
422toList = foldrM (\a xs -> return (a : xs)) []
420toList = foldrM (\a xs -> return (a : xs)) []
423
421
424-- | Take first 'n' elements from the stream and discard the rest.
422-- | Take first 'n' elements from the stream and discard the rest.
@@ -492,7 +490,7 @@ dropWhile p m = fromStream $ go (toStream m)
492-- | Determine whether all elements of a stream satisfy a predicate.
490-- | Determine whether all elements of a stream satisfy a predicate.
493--
491--
494-- @since 0.1.0
492-- @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
496all p m = go (toStream m)
494all p m = go (toStream m)
497 where
495 where
498 go m1 =
496 go m1 =
@@ -505,7 +503,7 @@ all p m = go (toStream m)
505-- | Determine whether any of the elements of a stream satisfy a predicate.
503-- | Determine whether any of the elements of a stream satisfy a predicate.
506--
504--
507-- @since 0.1.0
505-- @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
509any p m = go (toStream m)
507any p m = go (toStream m)
510 where
508 where
511 go m1 =
509 go m1 =
@@ -518,19 +516,19 @@ any p m = go (toStream m)
518-- | Determine the sum of all elements of a stream of numbers
516-- | Determine the sum of all elements of a stream of numbers
519--
517--
520-- @since 0.1.0
518-- @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
522sum = foldl (+) 0 id
520sum = foldl (+) 0 id
523
521
524-- | Determine the product of all elements of a stream of numbers
522-- | Determine the product of all elements of a stream of numbers
525--
523--
526-- @since 0.1.1
524-- @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
528product = foldl (*) 1 id
526product = foldl (*) 1 id
529
527
530-- | Extract the first element of the stream, if any.
528-- | Extract the first element of the stream, if any.
531--
529--
532-- @since 0.1.0
530-- @since 0.1.0
533−head :: Monad m => StreamT m a -> m (Maybe a)
531+head :: Monad m => SerialT m a -> m (Maybe a)
534head m =
532head m =
535 let stop = return Nothing
533 let stop = return Nothing
536 single a = return (Just a)
534 single a = return (Just a)
@@ -540,7 +538,7 @@ head m =
540-- | Extract all but the first element of the stream, if any.
538-- | Extract all but the first element of the stream, if any.
541--
539--
542-- @since 0.1.1
540-- @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))
544tail m =
542tail m =
545 let stop = return Nothing
543 let stop = return Nothing
546 single _ = return $ Just nil
544 single _ = return $ Just nil
@@ -551,13 +549,13 @@ tail m =
551--
549--
552-- @since 0.1.1
550-- @since 0.1.1
553{-# INLINE last #-}
551{-# INLINE last #-}
554−last :: Monad m => StreamT m a -> m (Maybe a)
552+last :: Monad m => SerialT m a -> m (Maybe a)
555last = foldl (\_ y -> Just y) Nothing id
553last = foldl (\_ y -> Just y) Nothing id
556
554
557-- | Determine whether the stream is empty.
555-- | Determine whether the stream is empty.
558--
556--
559-- @since 0.1.1
557-- @since 0.1.1
560−null :: Monad m => StreamT m a -> m Bool
558+null :: Monad m => SerialT m a -> m Bool
561null m =
559null m =
562 let stop = return True
560 let stop = return True
563 single _ = return False
561 single _ = return False
@@ -567,7 +565,7 @@ null m =
567-- | Determine whether an element is present in the stream.
565-- | Determine whether an element is present in the stream.
568--
566--
569-- @since 0.1.0
567-- @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
571elem e m = go (toStream m)
569elem e m = go (toStream m)
572 where
570 where
573 go m1 =
571 go m1 =
@@ -579,7 +577,7 @@ elem e m = go (toStream m)
579-- | Determine whether an element is not present in the stream.
577-- | Determine whether an element is not present in the stream.
580--
578--
581-- @since 0.1.0
579-- @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
583notElem e m = go (toStream m)
581notElem e m = go (toStream m)
584 where
582 where
585 go m1 =
583 go m1 =
@@ -591,7 +589,7 @@ notElem e m = go (toStream m)
591-- | Determine the length of the stream.
589-- | Determine the length of the stream.
592--
590--
593-- @since 0.1.0
591-- @since 0.1.0
594−length :: Monad m => StreamT m a -> m Int
592+length :: Monad m => SerialT m a -> m Int
595length = foldl (\n _ -> n + 1) 0 id
593length = foldl (\n _ -> n + 1) 0 id
596
594
597-- | Returns the elements of the stream in reverse order.
595-- | Returns the elements of the stream in reverse order.
@@ -612,7 +610,7 @@ reverse m = fromStream $ go S.nil (toStream m)
612-- | Determine the minimum element in a stream.
610-- | Determine the minimum element in a stream.
613--
611--
614-- @since 0.1.0
612-- @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)
616minimum m = go Nothing (toStream m)
614minimum m = go Nothing (toStream m)
617 where
615 where
618 go res m1 =
616 go res m1 =
@@ -629,7 +627,7 @@ minimum m = go Nothing (toStream m)
629-- | Determine the maximum element in a stream.
627-- | Determine the maximum element in a stream.
630--
628--
631-- @since 0.1.0
629-- @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)
633maximum m = go Nothing (toStream m)
631maximum m = go Nothing (toStream m)
634 where
632 where
635 go res m1 =
633 go res m1 =
@@ -665,7 +663,7 @@ mapM f m = fromStream $ go (toStream m)
665-- output of the action.
663-- output of the action.
666--
664--
667-- @since 0.1.0
665-- @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 ()
669mapM_ f m = go (toStream m)
667mapM_ f m = go (toStream m)
670 where
668 where
671 go m1 =
669 go m1 =
@@ -719,33 +717,19 @@ zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
719-- | Zip two streams concurrently (i.e. both the elements being zipped are
717-- | Zip two streams concurrently (i.e. both the elements being zipped are
720-- generated concurrently) using a pure zipping function.
718-- generated concurrently) using a pure zipping function.
721--
719--
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−-- |
729-- @since 0.1.0
720-- @since 0.1.0
730−{-# DEPRECATED zipAsyncWith "Please use zipParallelWith instead." #-}
731−zipAsyncWith :: (IsStream t, MonadParallel m)
721+zipAsyncWith :: (IsStream t, MonadAsync m)
732 => (a -> b -> c) -> t m a -> t m b -> t m c
722 => (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)
734
725
735-- | Zip two streams asyncly (i.e. both the elements being zipped are generated
726-- | Zip two streams asyncly (i.e. both the elements being zipped are generated
736-- concurrently) using a monadic zipping function.
727-- concurrently) using a monadic zipping function.
737--
728--
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−-- |
747-- @since 0.1.0
729-- @since 0.1.0
748−{-# DEPRECATED zipAsyncWithM "Please use zipParallelWithM instead." #-}
749−zipAsyncWithM :: (IsStream t, MonadParallel m)
730+zipAsyncWithM :: (IsStream t, MonadAsync m)
750 => (a -> b -> t m c) -> t m a -> t m b -> t m c
731 => (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
22 (
22 (
23 IsStream (..)
23 IsStream (..)
24 , Streaming -- deprecated
24 , Streaming -- deprecated
25− , MonadParallel
26− , S.MonadAsync -- deprecated
25+ , S.MonadAsync
27
26
28 -- * SVars
27 -- * SVars
29 , SVarSched (..)
28 , SVarSched (..)
@@ -49,51 +48,48 @@ module Streamly.Streams
49 , toSVar
48 , toSVar
50
49
51 -- * Transformation
50 -- * Transformation
52− , async
51+ , mkAsync
53
52
54 -- * Merging Streams
53 -- * Merging Streams
55− , splice
54+ , serial
56− , cosplice
55+ , wSerial
57− , parAhead
56+ , async
58− , coparAhead
57+ , wAsync
59 , parallel
58 , parallel
60 , (<=>) --deprecated
59 , (<=>) --deprecated
61 , (<|) --deprecated
60 , (<|) --deprecated
62
61
63 -- * IO Streams
62 -- * IO Streams
64− , Stream
63+ , Serial
65− , Costream
64+ , WSerial
66− , ParAhead
65+ , Async
67− , CoparAhead
66+ , WAsync
68 , Parallel
67 , Parallel
69− , ZipStream
68+ , ZipSerial
70− , ZipParallel
69+ , ZipAsync
71
70
72 -- * Stream Transformers
71 -- * Stream Transformers
72+ , SerialT
73− , StreamT
73+ , StreamT -- deprecated
74− , CostreamT
74+ , WSerialT
75 , InterleavedT -- deprecated
75 , InterleavedT -- deprecated
76− , ParAheadT
77− , AsyncT -- deprecated
76+ , AsyncT
78− , CoparAheadT
77+ , WAsyncT
79 , ParallelT
78 , ParallelT
80− , ZipStreamM
81− , ZipParallelM
82− , ZipAsync -- deprecated
79+ , ZipStream -- deprecated
80+ , ZipSerialM
81+ , ZipAsyncM
83
82
84 -- * Type Adapters
83 -- * Type Adapters
85− , asStream
86 , serially -- deprecated
84 , serially -- deprecated
87− , asCostream
85+ , wSerially
88 , interleaving -- deprecated
86 , interleaving -- deprecated
89− , asParAhead
90− , asyncly -- deprecated
87+ , asyncly
91− , asCoparAhead
88+ , wAsyncly
92− , asParallel
93− , parallely -- deprecated
89+ , parallely
94− , asZipStream
90+ , zipSerially
95 , zipping -- deprecated
91 , zipping -- deprecated
96− , asZipParallel
92+ , zipAsyncly
97 , zippingAsync -- deprecated
93 , zippingAsync -- deprecated
98 , adapt
94 , adapt
99
95
@@ -121,7 +117,7 @@ import Control.Monad.Reader.Class (MonadReader(..))
121import Control.Monad.State.Class (MonadState(..))
117import Control.Monad.State.Class (MonadState(..))
122import Control.Monad.Trans.Class (MonadTrans (lift))
118import Control.Monad.Trans.Class (MonadTrans (lift))
123import Data.Semigroup (Semigroup(..))
119import Data.Semigroup (Semigroup(..))
124−import Streamly.Core ( MonadParallel
120+import Streamly.Core ( MonadAsync
125 , SVar, SVarStyle(..)
121 , SVar, SVarStyle(..)
126 , SVarTag(..), SVarSched(..))
122 , SVarTag(..), SVarSched(..))
127import qualified Streamly.Core as S
123import qualified Streamly.Core as S
@@ -238,7 +234,7 @@ fromCallback :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
238fromCallback k = fromStream $ S.Stream $ \_ _ sng _ -> k sng
234fromCallback k = fromStream $ S.Stream $ \_ _ sng _ -> k sng
239
235
240-- | Read an SVar to get a stream.
236-- | 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
242fromSVar sv = fromStream $ S.fromStreamVar sv
238fromSVar sv = fromStream $ S.fromStreamVar sv
243
239
244------------------------------------------------------------------------------
240------------------------------------------------------------------------------
@@ -261,11 +257,11 @@ streamFold svr step single blank m =
261 in (S.runStream (toStream m)) svr blank single yield
257 in (S.runStream (toStream m)) svr blank single yield
262
258
263-- | Run a streaming composition, discard the results. By default it interprets
259-- | 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
260+-- the stream as 'SerialT', to run other types of streams use the type adapting
265−-- combinators for example @runStream . 'asParAhead'@.
261+-- combinators for example @runStream . 'asyncly'@.
266--
262--
267-- @since 0.2.0
263-- @since 0.2.0
268−runStream :: Monad m => StreamT m a -> m ()
264+runStream :: Monad m => SerialT m a -> m ()
269runStream m = go (toStream m)
265runStream m = go (toStream m)
270 where
266 where
271 go m1 =
267 go m1 =
@@ -283,7 +279,7 @@ runStreaming = runStream . adapt
283
279
284-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
280-- | Write a stream to an 'SVar' in a non-blocking manner. The stream can then
285-- be read back from the SVar using 'fromSVar'.
281-- 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 ()
287toSVar sv m = S.toStreamVar sv (toStream m)
283toSVar sv m = S.toStreamVar sv (toStream m)
288
284
289------------------------------------------------------------------------------
285------------------------------------------------------------------------------
@@ -297,9 +293,9 @@ toSVar sv m = S.toStreamVar sv (toStream m)
297-- not drained fully we may have a thread blocked forever and once exhausted it
293-- not drained fully we may have a thread blocked forever and once exhausted it
298-- will always return 'empty'.
294-- will always return 'empty'.
299--
295--
300−-- @since 0.1.0
296+-- @since 0.2.0
301−async :: (IsStream t, MonadParallel m) => t m a -> m (t m a)
297+mkAsync :: (IsStream t, MonadAsync m) => t m a -> m (t m a)
302−async m = do
298+mkAsync m = do
303 sv <- S.newStreamVar1 (SVarStyle Disjunction LIFO) (toStream m)
299 sv <- S.newStreamVar1 (SVarStyle Disjunction LIFO) (toStream m)
304 return $ fromSVar sv
300 return $ fromSVar sv
305
301
@@ -310,7 +306,7 @@ async m = do
310-- XXX use template haskell instead and include Monoid and IsStream instances
306-- XXX use template haskell instead and include Monoid and IsStream instances
311-- as well.
307-- as well.
312
308
313−#define MONADPARALLEL , MonadParallel m
309+#define MONADPARALLEL , MonadAsync m
314
310
315#define MONAD_APPLICATIVE_INSTANCE(STREAM,CONSTRAINT) \
311#define MONAD_APPLICATIVE_INSTANCE(STREAM,CONSTRAINT) \
316instance (Monad m CONSTRAINT) => Applicative (STREAM m) where { \
312instance (Monad m CONSTRAINT) => Applicative (STREAM m) where { \
@@ -344,25 +340,26 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
344 state k = lift (state k) }
340 state k = lift (state k) }
345
341
346------------------------------------------------------------------------------
342------------------------------------------------------------------------------
347−-- StreamT
343+-- SerialT
348------------------------------------------------------------------------------
344------------------------------------------------------------------------------
349
345
346+-- | Deep serial composition or serial composition with depth first traversal.
350−-- | The 'Semigroup' instance of 'StreamT' appends two streams sequentially,
347+-- The 'Semigroup' instance of 'SerialT' appends two streams serially in a
351−-- yielding all elements from the first stream, and then all elements from the
348+-- depth first manner, yielding all elements from the first stream, and then
352−-- second stream.
349+-- all elements from the second stream.
353--
350--
354-- @
351-- @
355−-- main = ('toList' . 'asStream' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
352+-- main = ('toList' . 'serially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
356-- @
353-- @
357-- @
354-- @
358-- [1,2,3,4]
355-- [1,2,3,4]
359-- @
356-- @
360--
357--
361-- The 'Monad' instance runs the /monadic continuation/ for each
358-- The 'Monad' instance runs the /monadic continuation/ for each
362−-- element of the stream, asStream.
359+-- element of the stream, serially.
363--
360--
364-- @
361-- @
365−-- main = 'runStream' . 'asStream' $ do
362+-- main = 'runStream' . 'serially' $ do
366-- x <- return 1 \<\> return 2
363-- x <- return 1 \<\> return 2
367-- liftIO $ print x
364-- liftIO $ print x
368-- @
365-- @
@@ -371,10 +368,10 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
371-- 2
368-- 2
372-- @
369-- @
373--
370--
374−-- 'StreamT' nests streams serially in a depth first manner.
371+-- 'SerialT' nests streams serially in a depth first manner.
375--
372--
376-- @
373-- @
377−-- main = 'runStream' . 'asStream' $ do
374+-- main = 'runStream' . 'serially' $ do
378-- x <- return 1 \<\> return 2
375-- x <- return 1 \<\> return 2
379-- y <- return 3 \<\> return 4
376-- y <- return 3 \<\> return 4
380-- liftIO $ print (x, y)
377-- liftIO $ print (x, y)
@@ -386,45 +383,51 @@ instance (MonadState s m CONSTRAINT) => MonadState s (STREAM m) where { \
386-- (2,4)
383-- (2,4)
387-- @
384-- @
388--
385--
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
390-- monadic code being run for each element of the stream a monadic
387-- monadic code being run for each element of the stream a monadic
391-- continuation. In imperative paradigm we can think of this composition as
388-- continuation. In imperative paradigm we can think of this composition as
392-- nested @for@ loops and the monadic continuation is the body of the loop. The
389-- nested @for@ loops and the monadic continuation is the body of the loop. The
393-- loop iterates for all elements of the stream.
390-- loop iterates for all elements of the stream.
394--
391--
395−-- The 'asStream' combinator can be omitted as the default stream type is
392+-- The 'serially' combinator can be omitted as the default stream type is
396−-- 'StreamT'.
393+-- 'SerialT'.
397−-- Note that serial composition can be used to combine an infinite number of
394+-- Note that serial composition with depth first traversal can be used to
398−-- streams as it explores only one stream at a time.
395+-- combine an infinite number of streams as it explores only one stream at a
396+-- time.
399--
397--
400−-- @since 0.1.0
398+-- @since 0.2.0
401−newtype StreamT m a = StreamT {getStreamT :: S.Stream m a}
399+newtype SerialT m a = SerialT {getSerialT :: S.Stream m a}
402 deriving (Semigroup, Monoid, Functor, MonadTrans)
400 deriving (Semigroup, Monoid, Functor, MonadTrans)
403
401
402+-- |
403+-- @since 0.1.0
404+{-# DEPRECATED StreamT "Please use 'SerialT' instead." #-}
405+type StreamT = SerialT
406+
404−instance IsStream StreamT where
407+instance IsStream SerialT where
405− toStream = getStreamT
408+ toStream = getSerialT
406− fromStream = StreamT
409+ fromStream = SerialT
407
410
408------------------------------------------------------------------------------
411------------------------------------------------------------------------------
409-- Semigroup
412-- Semigroup
410------------------------------------------------------------------------------
413------------------------------------------------------------------------------
411
414
412−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'StreamT'.
415+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'SerialT'.
413-- Appends two streams sequentially, yielding all elements from the first
416-- Appends two streams sequentially, yielding all elements from the first
414-- stream, and then all elements from the second stream.
417-- stream, and then all elements from the second stream.
415--
418--
416-- @since 0.2.0
419-- @since 0.2.0
417−{-# INLINE splice #-}
420+{-# INLINE serial #-}
418−splice :: IsStream t => t m a -> t m a -> t m a
421+serial :: IsStream t => t m a -> t m a -> t m a
419−splice m1 m2 = fromStream $ S.splice (toStream m1) (toStream m2)
422+serial m1 m2 = fromStream $ S.serial (toStream m1) (toStream m2)
420
423
421------------------------------------------------------------------------------
424------------------------------------------------------------------------------
422-- Monad
425-- Monad
423------------------------------------------------------------------------------
426------------------------------------------------------------------------------
424
427
425−instance Monad m => Monad (StreamT m) where
428+instance Monad m => Monad (SerialT m) where
426 return = pure
429 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 ->
428 let run x = (S.runStream x) Nothing stp sng yld
431 let run x = (S.runStream x) Nothing stp sng yld
429 single a = run $ toStream (f a)
432 single a = run $ toStream (f a)
430 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
433 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
@@ -434,29 +437,31 @@ instance Monad m => Monad (StreamT m) where
434-- Other instances
437-- Other instances
435------------------------------------------------------------------------------
438------------------------------------------------------------------------------
436
439
437−MONAD_APPLICATIVE_INSTANCE(StreamT,)
440+MONAD_APPLICATIVE_INSTANCE(SerialT,)
438−MONAD_COMMON_INSTANCES(StreamT,)
441+MONAD_COMMON_INSTANCES(SerialT,)
439
442
440------------------------------------------------------------------------------
443------------------------------------------------------------------------------
441−-- CostreamT
444+-- WSerialT
442------------------------------------------------------------------------------
445------------------------------------------------------------------------------
443
446
447+-- | Wide serial composition or serial composition with a breadth first
444−-- | The 'Semigroup' instance of 'CostreamT' interleaves two streams,
448+-- traversal. The 'Semigroup' instance of 'WSerialT' traverses
449+-- the two streams in a breadth first manner. In other words, it interleaves
445−-- yielding one element from each stream alternately.
450+-- two streams, yielding one element from each stream alternately.
446--
451--
447-- @
452-- @
448−-- main = ('toList' . 'asCostream' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
453+-- main = ('toList' . 'wSerially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
449-- @
454-- @
450-- @
455-- @
451-- [1,3,2,4]
456-- [1,3,2,4]
452-- @
457-- @
453--
458--
454−-- Similarly, the 'Monad' instance fairly interleaves the iterations of the
459+-- Similarly, the 'Monad' instance interleaves the iterations of the
455-- inner and the outer loop, nesting loops in a breadth first manner.
460-- inner and the outer loop, nesting loops in a breadth first manner.
456--
461--
457--
462--
458-- @
463-- @
459−-- main = 'runStream' . 'asCostream' $ do
464+-- main = 'runStream' . 'wSerially' $ do
460-- x <- return 1 \<\> return 2
465-- x <- return 1 \<\> return 2
461-- y <- return 3 \<\> return 4
466-- y <- return 3 \<\> return 4
462-- liftIO $ print (x, y)
467-- liftIO $ print (x, y)
@@ -468,52 +473,53 @@ MONAD_COMMON_INSTANCES(StreamT,)
468-- (2,4)
473-- (2,4)
469-- @
474-- @
470--
475--
471−-- Note that a 'Costream' composition can only combine a finite number of
476+-- Note that a serial composition with breadth first traversal can only combine
472−-- streams as it needs to retain state for each unfinished stream.
477+-- a finite number of streams as it needs to retain state for each unfinished
478+-- stream.
473--
479--
474-- @since 0.2.0
480-- @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}
476 deriving (Functor, MonadTrans)
482 deriving (Functor, MonadTrans)
477
483
478-- |
484-- |
479-- @since 0.1.0
485-- @since 0.1.0
480−{-# DEPRECATED InterleavedT "Please use 'CostreamT' instead." #-}
486+{-# DEPRECATED InterleavedT "Please use 'WSerialT' instead." #-}
481−type InterleavedT = CostreamT
487+type InterleavedT = WSerialT
482
488
483−instance IsStream CostreamT where
489+instance IsStream WSerialT where
484− toStream = getCostreamT
490+ toStream = getWSerialT
485− fromStream = CostreamT
491+ fromStream = WSerialT
486
492
487------------------------------------------------------------------------------
493------------------------------------------------------------------------------
488-- Semigroup
494-- Semigroup
489------------------------------------------------------------------------------
495------------------------------------------------------------------------------
490
496
491−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'CostreamT'.
497+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
492-- Interleaves two streams, yielding one element from each stream alternately.
498-- Interleaves two streams, yielding one element from each stream alternately.
493--
499--
494-- @since 0.2.0
500-- @since 0.2.0
495−{-# INLINE cosplice #-}
501+{-# INLINE wSerial #-}
496−cosplice :: IsStream t => t m a -> t m a -> t m a
502+wSerial :: IsStream t => t m a -> t m a -> t m a
497−cosplice m1 m2 = fromStream $ S.cosplice (toStream m1) (toStream m2)
503+wSerial m1 m2 = fromStream $ S.wSerial (toStream m1) (toStream m2)
498
504
499−instance Semigroup (CostreamT m a) where
505+instance Semigroup (WSerialT m a) where
500− (<>) = cosplice
506+ (<>) = wSerial
501
507
502infixr 5 <=>
508infixr 5 <=>
503
509
504−-- | Same as 'cosplice'.
510+-- | Same as 'wSerial'.
505--
511--
506-- @since 0.1.0
512-- @since 0.1.0
507−{-# DEPRECATED (<=>) "Please use 'cosplice' instead." #-}
513+{-# DEPRECATED (<=>) "Please use 'wSerial' instead." #-}
508{-# INLINE (<=>) #-}
514{-# INLINE (<=>) #-}
509(<=>) :: IsStream t => t m a -> t m a -> t m a
515(<=>) :: IsStream t => t m a -> t m a -> t m a
510−(<=>) = cosplice
516+(<=>) = wSerial
511
517
512------------------------------------------------------------------------------
518------------------------------------------------------------------------------
513-- Monoid
519-- Monoid
514------------------------------------------------------------------------------
520------------------------------------------------------------------------------
515
521
516−instance Monoid (CostreamT m a) where
522+instance Monoid (WSerialT m a) where
517 mempty = nil
523 mempty = nil
518 mappend = (<>)
524 mappend = (<>)
519
525
@@ -521,9 +527,9 @@ instance Monoid (CostreamT m a) where
521-- Monad
527-- Monad
522------------------------------------------------------------------------------
528------------------------------------------------------------------------------
523
529
524−instance Monad m => Monad (CostreamT m) where
530+instance Monad m => Monad (WSerialT m) where
525 return = pure
531 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 ->
527 let run x = (S.runStream x) Nothing stp sng yld
533 let run x = (S.runStream x) Nothing stp sng yld
528 single a = run $ toStream (f a)
534 single a = run $ toStream (f a)
529 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
535 yield a r = run $ toStream $ f a <> (fromStream r >>= f)
@@ -533,21 +539,21 @@ instance Monad m => Monad (CostreamT m) where
533-- Other instances
539-- Other instances
534------------------------------------------------------------------------------
540------------------------------------------------------------------------------
535
541
536−MONAD_APPLICATIVE_INSTANCE(CostreamT,)
542+MONAD_APPLICATIVE_INSTANCE(WSerialT,)
537−MONAD_COMMON_INSTANCES(CostreamT,)
543+MONAD_COMMON_INSTANCES(WSerialT,)
538
544
539------------------------------------------------------------------------------
545------------------------------------------------------------------------------
540−-- ParAheadT
546+-- AsyncT
541------------------------------------------------------------------------------
547------------------------------------------------------------------------------
542
548
549+-- | Deep async composition or async composition with depth first traversal. In
543−-- | Adaptive ahead parallel, in a left to right 'Semigroup' composition it tries to
550+-- a left to right 'Semigroup' composition it tries to yield elements from the
544−-- yield elements from the left stream as long as it can, but it can run the
551+-- left stream as long as it can, but it can run the right stream in parallel
545−-- right stream in parallel if it needs to, based on demand. The right stream
552+-- if it needs to, based on demand. The right stream can be run if the left
546−-- can be run if the left stream blocks on IO or cannot produce elements fast
553+-- stream blocks on IO or cannot produce elements fast enough for the consumer.
547−-- enough for the consumer.
548--
554--
549-- @
555-- @
550−-- main = ('toList' . 'asParAhead' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
556+-- main = ('toList' . 'asyncly' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
551-- @
557-- @
552-- @
558-- @
553-- [1,2,3,4]
559-- [1,2,3,4]
@@ -560,7 +566,7 @@ MONAD_COMMON_INSTANCES(CostreamT,)
560-- different streams in the resulting stream can vary depending on scheduling
566-- different streams in the resulting stream can vary depending on scheduling
561-- and generation delays.
567-- and generation delays.
562--
568--
563−-- Similarly, the monad instance of 'CoparAheadT' /may/ run each iteration
569+-- Similarly, the monad instance of 'AsyncT' /may/ run each iteration
564-- concurrently based on demand. More concurrent iterations are started only
570-- concurrently based on demand. More concurrent iterations are started only
565-- if the previous iterations are not able to produce enough output for the
571-- if the previous iterations are not able to produce enough output for the
566-- consumer.
572-- consumer.
@@ -569,7 +575,7 @@ MONAD_COMMON_INSTANCES(CostreamT,)
569-- import "Streamly"
575-- import "Streamly"
570-- import Control.Concurrent
576-- import Control.Concurrent
571--
577--
572−-- main = 'runStream' . 'asParAhead' $ do
578+-- main = 'runStream' . 'asyncly' $ do
573-- n <- return 3 \<\> return 2 \<\> return 1
579-- n <- return 3 \<\> return 2 \<\> return 1
574-- liftIO $ do
580-- liftIO $ do
575-- threadDelay (n * 1000000)
581-- threadDelay (n * 1000000)
@@ -583,51 +589,47 @@ MONAD_COMMON_INSTANCES(CostreamT,)
583--
589--
584-- All iterations may run in the same thread if they do not block.
590-- All iterations may run in the same thread if they do not block.
585--
591--
586−-- Note that this composition can be used to combine infinite number of streams
592+-- Note that async composition with depth first traversal can be used to
587−-- as it explores only a bounded number of streams at a time.
593+-- combine infinite number of streams as it explores only a bounded number of
594+-- streams at a time.
588--
595--
589−-- @since 0.2.0
590−newtype ParAheadT m a = ParAheadT {getParAheadT :: S.Stream m a}
591− deriving (Functor, MonadTrans)
592−
593−-- |
594-- @since 0.1.0
596-- @since 0.1.0
595−{-# DEPRECATED AsyncT "Please use 'ParAheadT' instead." #-}
597+newtype AsyncT m a = AsyncT {getAsyncT :: S.Stream m a}
596−type AsyncT = ParAheadT
598+ deriving (Functor, MonadTrans)
597
599
598−instance IsStream ParAheadT where
600+instance IsStream AsyncT where
599− toStream = getParAheadT
601+ toStream = getAsyncT
600− fromStream = ParAheadT
602+ fromStream = AsyncT
601
603
602------------------------------------------------------------------------------
604------------------------------------------------------------------------------
603-- Semigroup
605-- Semigroup
604------------------------------------------------------------------------------
606------------------------------------------------------------------------------
605
607
606−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'ParAheadT'.
608+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AsyncT'.
607-- Merges two streams possibly concurrently, preferring the
609-- Merges two streams possibly concurrently, preferring the
608-- elements from the left one when available.
610-- elements from the left one when available.
609--
611--
610-- @since 0.2.0
612-- @since 0.2.0
611−{-# INLINE parAhead #-}
613+{-# INLINE async #-}
612−parAhead :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
614+async :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
613−parAhead m1 m2 = fromStream $ S.parAhead (toStream m1) (toStream m2)
615+async m1 m2 = fromStream $ S.async (toStream m1) (toStream m2)
614
616
615−instance MonadParallel m => Semigroup (ParAheadT m a) where
617+instance MonadAsync m => Semigroup (AsyncT m a) where
616− (<>) = parAhead
618+ (<>) = async
617
619
618−-- | Same as 'parAhead'.
620+-- | Same as 'async'.
619--
621--
620-- @since 0.1.0
622-- @since 0.1.0
621−{-# DEPRECATED (<|) "Please use 'parAhead' instead." #-}
623+{-# DEPRECATED (<|) "Please use 'async' instead." #-}
622{-# INLINE (<|) #-}
624{-# INLINE (<|) #-}
623−(<|) :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
625+(<|) :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
624−(<|) = parAhead
626+(<|) = async
625
627
626------------------------------------------------------------------------------
628------------------------------------------------------------------------------
627-- Monoid
629-- Monoid
628------------------------------------------------------------------------------
630------------------------------------------------------------------------------
629
631
630−instance MonadParallel m => Monoid (ParAheadT m a) where
632+instance MonadAsync m => Monoid (AsyncT m a) where
631 mempty = nil
633 mempty = nil
632 mappend = (<>)
634 mappend = (<>)
633
635
@@ -650,28 +652,28 @@ parbind par m f = go m
650 yield a r = run $ f a `par` go r
652 yield a r = run $ f a `par` go r
651 in g Nothing stp single yield
653 in g Nothing stp single yield
652
654
653−instance MonadParallel m => Monad (ParAheadT m) where
655+instance MonadAsync m => Monad (AsyncT m) where
654 return = pure
656 return = pure
655− (ParAheadT m) >>= f = ParAheadT $ parbind S.parAhead m (getParAheadT . f)
657+ (AsyncT m) >>= f = AsyncT $ parbind S.async m (getAsyncT . f)
656
658
657------------------------------------------------------------------------------
659------------------------------------------------------------------------------
658-- Other instances
660-- Other instances
659------------------------------------------------------------------------------
661------------------------------------------------------------------------------
660
662
661−MONAD_APPLICATIVE_INSTANCE(ParAheadT,MONADPARALLEL)
663+MONAD_APPLICATIVE_INSTANCE(AsyncT,MONADPARALLEL)
662−MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
664+MONAD_COMMON_INSTANCES(AsyncT, MONADPARALLEL)
663
665
664------------------------------------------------------------------------------
666------------------------------------------------------------------------------
665−-- CoparAheadT
667+-- WAsyncT
666------------------------------------------------------------------------------
668------------------------------------------------------------------------------
667
669
668−-- | Round robin concurrent composition.
670+-- | Wide async composition or async composition with breadth first traversal.
669−--
670−-- The Semigroup instance of 'CoparAheadT' concurrently /merges/ streams in a
671+-- The Semigroup instance of 'WAsyncT' concurrently /traverses/ the composed
672+-- streams using a depth first travesal or in a round robin fashion, yielding
671−-- round robin fashion, yielding elements from both streams alternately.
673+-- elements from both streams alternately.
672--
674--
673-- @
675-- @
674−-- main = ('toList' . 'asCoparAhead' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
676+-- main = ('toList' . 'wAsyncly' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
675-- @
677-- @
676-- @
678-- @
677-- [1,3,2,4]
679-- [1,3,2,4]
@@ -684,14 +686,14 @@ MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
684-- different streams in the resulting stream can vary depending on scheduling
686-- different streams in the resulting stream can vary depending on scheduling
685-- and generation delays.
687-- and generation delays.
686--
688--
687−-- Similarly, the 'Monad' instance of 'CoparAheadT' runs /all/ iterations fairly
689+-- Similarly, the 'Monad' instance of 'WAsyncT' runs /all/ iterations fairly
688-- concurrently using a round robin scheduling.
690-- concurrently using a round robin scheduling.
689--
691--
690-- @
692-- @
691-- import "Streamly"
693-- import "Streamly"
692-- import Control.Concurrent
694-- import Control.Concurrent
693--
695--
694−-- main = 'runStream' . 'asCoparAhead' $ do
696+-- main = 'runStream' . 'wAsyncly' $ do
695-- n <- return 3 \<\> return 2 \<\> return 1
697-- n <- return 3 \<\> return 2 \<\> return 1
696-- liftIO $ do
698-- liftIO $ do
697-- threadDelay (n * 1000000)
699-- threadDelay (n * 1000000)
@@ -703,40 +705,41 @@ MONAD_COMMON_INSTANCES(ParAheadT, MONADPARALLEL)
703-- ThreadId 38: Delay 3
705-- ThreadId 38: Delay 3
704-- @
706-- @
705--
707--
706−-- Unlike 'ParAheadT' all iterations are guaranteed to run fairly
708+-- Unlike 'AsyncT' all iterations are guaranteed to run fairly
707-- concurrently, unconditionally.
709-- concurrently, unconditionally.
708--
710--
709−-- Note that round robin composition can only combine a finite number of
711+-- Note that async composition with breadth first traversal can only combine a
710−-- streams as it needs to retain state for each unfinished stream.
712+-- finite number of streams as it needs to retain state for each unfinished
713+-- stream.
711--
714--
712−-- @since 0.1.0
715+-- @since 0.2.0
713−newtype CoparAheadT m a = CoparAheadT {getCoparAheadT :: S.Stream m a}
716+newtype WAsyncT m a = WAsyncT {getWAsyncT :: S.Stream m a}
714 deriving (Functor, MonadTrans)
717 deriving (Functor, MonadTrans)
715
718
716−instance IsStream CoparAheadT where
719+instance IsStream WAsyncT where
717− toStream = getCoparAheadT
720+ toStream = getWAsyncT
718− fromStream = CoparAheadT
721+ fromStream = WAsyncT
719
722
720------------------------------------------------------------------------------
723------------------------------------------------------------------------------
721-- Semigroup
724-- Semigroup
722------------------------------------------------------------------------------
725------------------------------------------------------------------------------
723
726
724−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'CoparAheadT'.
727+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WAsyncT'.
725-- Merges two streams concurrently choosing elements from both fairly.
728-- Merges two streams concurrently choosing elements from both fairly.
726--
729--
727-- @since 0.2.0
730-- @since 0.2.0
728−{-# INLINE coparAhead #-}
731+{-# INLINE wAsync #-}
729−coparAhead :: (IsStream t, MonadParallel m) => t m a -> t m a -> t m a
732+wAsync :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
730−coparAhead m1 m2 = fromStream $ S.coparAhead (toStream m1) (toStream m2)
733+wAsync m1 m2 = fromStream $ S.wAsync (toStream m1) (toStream m2)
731
734
732−instance MonadParallel m => Semigroup (CoparAheadT m a) where
735+instance MonadAsync m => Semigroup (WAsyncT m a) where
733− (<>) = coparAhead
736+ (<>) = wAsync
734
737
735------------------------------------------------------------------------------
738------------------------------------------------------------------------------
736-- Monoid
739-- Monoid
737------------------------------------------------------------------------------
740------------------------------------------------------------------------------
738
741
739−instance MonadParallel m => Monoid (CoparAheadT m a) where
742+instance MonadAsync m => Monoid (WAsyncT m a) where
740 mempty = nil
743 mempty = nil
741 mappend = (<>)
744 mappend = (<>)
742
745
@@ -744,23 +747,23 @@ instance MonadParallel m => Monoid (CoparAheadT m a) where
744-- Monad
747-- Monad
745------------------------------------------------------------------------------
748------------------------------------------------------------------------------
746
749
747−instance MonadParallel m => Monad (CoparAheadT m) where
750+instance MonadAsync m => Monad (WAsyncT m) where
748 return = pure
751 return = pure
749− (CoparAheadT m) >>= f =
752+ (WAsyncT m) >>= f =
750− CoparAheadT $ parbind S.coparAhead m (getCoparAheadT . f)
753+ WAsyncT $ parbind S.wAsync m (getWAsyncT . f)
751
754
752------------------------------------------------------------------------------
755------------------------------------------------------------------------------
753-- Other instances
756-- Other instances
754------------------------------------------------------------------------------
757------------------------------------------------------------------------------
755
758
756−MONAD_APPLICATIVE_INSTANCE(CoparAheadT,MONADPARALLEL)
759+MONAD_APPLICATIVE_INSTANCE(WAsyncT,MONADPARALLEL)
757−MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
760+MONAD_COMMON_INSTANCES(WAsyncT, MONADPARALLEL)
758
761
759------------------------------------------------------------------------------
762------------------------------------------------------------------------------
760-- ParallelT
763-- ParallelT
761------------------------------------------------------------------------------
764------------------------------------------------------------------------------
762
765
763−-- | Strictly parallel composition.
766+-- | Async composition with simultaneous traversal of all streams.
764--
767--
765-- The Semigroup instance of 'ParallelT' concurrently /merges/ two streams,
768-- The Semigroup instance of 'ParallelT' concurrently /merges/ two streams,
766-- running both strictly concurrently and yielding elements from both streams
769-- running both strictly concurrently and yielding elements from both streams
@@ -768,7 +771,7 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
768-- one is evaluated in its own thread and the results produced are presented in
771-- one is evaluated in its own thread and the results produced are presented in
769-- the combined stream on a first come first serve basis.
772-- the combined stream on a first come first serve basis.
770--
773--
771−-- 'ParAheadT' and 'CoparAheadT' are /concurrent lookahead streams/ each with a
774+-- 'AsyncT' and 'WAsyncT' are /concurrent lookahead streams/ each with a
772-- specific type of consumption pattern (depth first or breadth first). Since
775-- specific type of consumption pattern (depth first or breadth first). Since
773-- they are lookahead, they may introduce certain default latency in starting
776-- they are lookahead, they may introduce certain default latency in starting
774-- more concurrent tasks for efficiency reasons or may put a default limitation
777-- more concurrent tasks for efficiency reasons or may put a default limitation
@@ -778,12 +781,12 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
778-- the desired rate. However, 'ParallelT' uses a separate runtime thread to
781-- the desired rate. However, 'ParallelT' uses a separate runtime thread to
779-- evaluate each stream.
782-- evaluate each stream.
780--
783--
781−-- 'CoparAheadT' is similar to 'ParallelT', as both of them evaluate the
784+-- 'WAsyncT' is similar to 'ParallelT', as both of them evaluate the
782-- constituent streams fairly in a round robin fashion.
785-- 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
784-- whereas 'ParallelT' is strict or push driven. 'ParallelT' immediately
787-- whereas 'ParallelT' is strict or push driven. 'ParallelT' immediately
785-- starts concurrent evaluation of both the streams (in separate threads) and
788-- 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
787-- threshold before initiating concurrent evaluation of the next stream. The
790-- threshold before initiating concurrent evaluation of the next stream. The
788-- concurrent scheduling of the next stream or the degree of concurrency is
791-- concurrent scheduling of the next stream or the degree of concurrency is
789-- driven by the feedback from the consumer. In case of 'ParallelT' each stream
792-- driven by the feedback from the consumer. In case of 'ParallelT' each stream
@@ -801,18 +804,18 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
801-- two tasks and want to start both strictly at the same time or if we have
804-- two tasks and want to start both strictly at the same time or if we have
802-- timers in the parallel tasks and our results depend on the timers being
805-- timers in the parallel tasks and our results depend on the timers being
803-- started at the same time. We can say that 'ParallelT' is almost the same
806-- 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
805-- used with unlimited lookahead and zero latency in initiating lookahead.
808-- used with unlimited lookahead and zero latency in initiating lookahead.
806--
809--
807-- @
810-- @
808−-- main = ('toList' . 'asParallel' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
811+-- main = ('toList' . 'parallely' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
809-- @
812-- @
810-- @
813-- @
811-- [1,3,2,4]
814-- [1,3,2,4]
812-- @
815-- @
813--
816--
814-- When streams with more than one element are merged, it yields whichever
817-- 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.
816--
819--
817-- Any exceptions generated by a constituent stream are propagated to the
820-- Any exceptions generated by a constituent stream are propagated to the
818-- output stream. The output and exceptions from a single stream are guaranteed
821-- output stream. The output and exceptions from a single stream are guaranteed
@@ -828,7 +831,7 @@ MONAD_COMMON_INSTANCES(CoparAheadT, MONADPARALLEL)
828-- import "Streamly"
831-- import "Streamly"
829-- import Control.Concurrent
832-- import Control.Concurrent
830--
833--
831−-- main = 'runStream' . 'asParallel' $ do
834+-- main = 'runStream' . 'parallely' $ do
832-- n <- return 3 \<\> return 2 \<\> return 1
835-- n <- return 3 \<\> return 2 \<\> return 1
833-- liftIO $ do
836-- liftIO $ do
834-- threadDelay (n * 1000000)
837-- threadDelay (n * 1000000)
@@ -860,17 +863,17 @@ instance IsStream ParallelT where
860--
863--
861-- @since 0.2.0
864-- @since 0.2.0
862{-# INLINE parallel #-}
865{-# 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
864parallel m1 m2 = fromStream $ S.parallel (toStream m1) (toStream m2)
867parallel m1 m2 = fromStream $ S.parallel (toStream m1) (toStream m2)
865
868
866−instance MonadParallel m => Semigroup (ParallelT m a) where
869+instance MonadAsync m => Semigroup (ParallelT m a) where
867 (<>) = parallel
870 (<>) = parallel
868
871
869------------------------------------------------------------------------------
872------------------------------------------------------------------------------
870-- Monoid
873-- Monoid
871------------------------------------------------------------------------------
874------------------------------------------------------------------------------
872
875
873−instance MonadParallel m => Monoid (ParallelT m a) where
876+instance MonadAsync m => Monoid (ParallelT m a) where
874 mempty = nil
877 mempty = nil
875 mappend = (<>)
878 mappend = (<>)
876
879
@@ -878,7 +881,7 @@ instance MonadParallel m => Monoid (ParallelT m a) where
878-- Monad
881-- Monad
879------------------------------------------------------------------------------
882------------------------------------------------------------------------------
880
883
881−instance MonadParallel m => Monad (ParallelT m) where
884+instance MonadAsync m => Monad (ParallelT m) where
882 return = pure
885 return = pure
883 (ParallelT m) >>= f = ParallelT $ parbind S.parallel m (getParallelT . f)
886 (ParallelT m) >>= f = ParallelT $ parbind S.parallel m (getParallelT . f)
884
887
@@ -893,12 +896,12 @@ MONAD_COMMON_INSTANCES(ParallelT, MONADPARALLEL)
893-- Serially Zipping Streams
896-- Serially Zipping Streams
894------------------------------------------------------------------------------
897------------------------------------------------------------------------------
895
898
896−-- | The applicative instance of 'ZipStreamM' zips a number of streams serially
899+-- | The applicative instance of 'ZipSerialM' zips a number of streams serially
897-- i.e. it produces one element from each stream serially and then zips all
900-- i.e. it produces one element from each stream serially and then zips all
898-- those elements.
901-- those elements.
899--
902--
900-- @
903-- @
901−-- main = (toList . 'asZipStream' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
904+-- main = (toList . 'zipSerially' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
902-- where s1 = fromFoldable [1, 2]
905-- where s1 = fromFoldable [1, 2]
903-- s2 = fromFoldable [3, 4]
906-- s2 = fromFoldable [3, 4]
904-- s3 = fromFoldable [5, 6]
907-- s3 = fromFoldable [5, 6]
@@ -908,29 +911,34 @@ MONAD_COMMON_INSTANCES(ParallelT, MONADPARALLEL)
908-- @
911-- @
909--
912--
910-- The 'Semigroup' instance of this type works the same way as that of
913-- The 'Semigroup' instance of this type works the same way as that of
911−-- 'StreamT'.
914+-- 'SerialT'.
912--
915--
913-- @since 0.2.0
916-- @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}
915 deriving (Functor, Semigroup, Monoid)
918 deriving (Functor, Semigroup, Monoid)
916
919
917−instance IsStream ZipStreamM where
920+-- |
918− toStream = getZipStreamM
921+-- @since 0.1.0
919− fromStream = ZipStreamM
922+{-# DEPRECATED ZipStream "Please use 'ZipSerialM' instead." #-}
923+type ZipStream = ZipSerialM
920
924
925+instance IsStream ZipSerialM where
926+ toStream = getZipSerialM
927+ fromStream = ZipSerialM
928+
921−instance Monad m => Applicative (ZipStreamM m) where
929+instance Monad m => Applicative (ZipSerialM m) where
922− pure = ZipStreamM . S.repeat
930+ pure = ZipSerialM . S.repeat
923 m1 <*> m2 = fromStream $ S.zipWith id (toStream m1) (toStream m2)
931 m1 <*> m2 = fromStream $ S.zipWith id (toStream m1) (toStream m2)
924
932
925------------------------------------------------------------------------------
933------------------------------------------------------------------------------
926-- Parallely Zipping Streams
934-- Parallely Zipping Streams
927------------------------------------------------------------------------------
935------------------------------------------------------------------------------
928
936
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
930-- be zipped concurrently.
938-- be zipped concurrently.
931--
939--
932-- @
940-- @
933−-- main = (toList . 'asZipParallel' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
941+-- main = (toList . 'zipAsyncly' $ (,,) \<$\> s1 \<*\> s2 \<*\> s3) >>= print
934-- where s1 = fromFoldable [1, 2]
942-- where s1 = fromFoldable [1, 2]
935-- s2 = fromFoldable [3, 4]
943-- s2 = fromFoldable [3, 4]
936-- s3 = fromFoldable [5, 6]
944-- s3 = fromFoldable [5, 6]
@@ -940,24 +948,19 @@ instance Monad m => Applicative (ZipStreamM m) where
940-- @
948-- @
941--
949--
942-- The 'Semigroup' instance of this type works the same way as that of
950-- The 'Semigroup' instance of this type works the same way as that of
943−-- 'StreamT'.
951+-- 'SerialT'.
944--
952--
945-- @since 0.2.0
953-- @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}
947 deriving (Functor, Semigroup, Monoid)
955 deriving (Functor, Semigroup, Monoid)
948
956
949−-- |
950−-- @since 0.1.0
951−{-# DEPRECATED ZipAsync "Please use ZipParallelM instead." #-}
952−type ZipAsync = ZipParallelM
953−
954−instance IsStream ZipParallelM where
957+instance IsStream ZipAsyncM where
955− toStream = getZipParallelM
958+ toStream = getZipAsyncM
956− fromStream = ZipParallelM
959+ fromStream = ZipAsyncM
957
960
958−instance MonadParallel m => Applicative (ZipParallelM m) where
961+instance MonadAsync m => Applicative (ZipAsyncM m) where
959− pure = ZipParallelM . S.repeat
962+ pure = ZipAsyncM . S.repeat
960− m1 <*> m2 = fromStream $ S.zipParallelWith id (toStream m1) (toStream m2)
963+ m1 <*> m2 = fromStream $ S.zipAsyncWith id (toStream m1) (toStream m2)
961
964
962-------------------------------------------------------------------------------
965-------------------------------------------------------------------------------
963-- Type adapting combinators
966-- Type adapting combinators
@@ -969,89 +972,68 @@ instance MonadParallel m => Applicative (ZipParallelM m) where
969adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
972adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
970adapt = fromStream . toStream
973adapt = fromStream . toStream
971
974
972−-- | Fix the type of a polymorphic stream as 'StreamT'.
975+-- | Fix the type of a polymorphic stream as 'SerialT'.
973−--
974−-- @since 0.2.0
975−asStream :: IsStream t => StreamT m a -> t m a
976−asStream = adapt
977−
978−-- | Same as 'asStream'.
979--
976--
980-- @since 0.1.0
977-- @since 0.1.0
981−{-# DEPRECATED serially "Please use asStream instead." #-}
982−serially :: IsStream t => StreamT m a -> t m a
978+serially :: IsStream t => SerialT m a -> t m a
983−serially = asStream
979+serially = adapt
984
980
985−-- | Fix the type of a polymorphic stream as 'CostreamT'.
981+-- | Fix the type of a polymorphic stream as 'WSerialT'.
986--
982--
987-- @since 0.2.0
983-- @since 0.2.0
988−asCostream :: IsStream t => CostreamT m a -> t m a
984+wSerially :: IsStream t => WSerialT m a -> t m a
989−asCostream = adapt
985+wSerially = adapt
990
986
991−-- | Same as 'asCostream'.
987+-- | Same as 'wSerially'.
992--
988--
993-- @since 0.1.0
989-- @since 0.1.0
994−{-# DEPRECATED interleaving "Please use asCostream instead." #-}
990+{-# DEPRECATED interleaving "Please use wSerially instead." #-}
995−interleaving :: IsStream t => CostreamT m a -> t m a
991+interleaving :: IsStream t => WSerialT m a -> t m a
996−interleaving = asCostream
992+interleaving = wSerially
997
993
998−-- | Fix the type of a polymorphic stream as 'ParAheadT'.
994+-- | Fix the type of a polymorphic stream as 'AsyncT'.
999−--
1000−-- @since 0.2.0
1001−asParAhead :: IsStream t => ParAheadT m a -> t m a
1002−asParAhead = adapt
1003−
1004−-- | Same as 'asParAhead'.
1005--
995--
1006-- @since 0.1.0
996-- @since 0.1.0
1007−{-# DEPRECATED asyncly "Please use asParAhead instead." #-}
1008−asyncly :: IsStream t => ParAheadT m a -> t m a
997+asyncly :: IsStream t => AsyncT m a -> t m a
1009−asyncly = asParAhead
998+asyncly = adapt
1010
999
1011−-- | Fix the type of a polymorphic stream as 'CoparAheadT'.
1000+-- | Fix the type of a polymorphic stream as 'WAsyncT'.
1012--
1001--
1013−-- @since 0.1.0
1002+-- @since 0.2.0
1014−asCoparAhead :: IsStream t => CoparAheadT m a -> t m a
1003+wAsyncly :: IsStream t => WAsyncT m a -> t m a
1015−asCoparAhead = adapt
1004+wAsyncly = adapt
1016
1005
1017-- | Fix the type of a polymorphic stream as 'ParallelT'.
1006-- | Fix the type of a polymorphic stream as 'ParallelT'.
1018--
1007--
1019-- @since 0.1.0
1008-- @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." #-}
1027parallely :: IsStream t => ParallelT m a -> t m a
1009parallely :: IsStream t => ParallelT m a -> t m a
1028−parallely = asParallel
1010+parallely = adapt
1029
1011
1030−-- | Fix the type of a polymorphic stream as 'ZipStreamM'.
1012+-- | Fix the type of a polymorphic stream as 'ZipSerialM'.
1031--
1013--
1032-- @since 0.2.0
1014-- @since 0.2.0
1033−asZipStream :: IsStream t => ZipStreamM m a -> t m a
1015+zipSerially :: IsStream t => ZipSerialM m a -> t m a
1034−asZipStream = adapt
1016+zipSerially = adapt
1035
1017
1036−-- | Same as 'asZipStream'.
1018+-- | Same as 'zipSerially'.
1037--
1019--
1038-- @since 0.1.0
1020-- @since 0.1.0
1039−{-# DEPRECATED zipping "Please use asZipStream instead." #-}
1021+{-# DEPRECATED zipping "Please use zipSerially instead." #-}
1040−zipping :: IsStream t => ZipStreamM m a -> t m a
1022+zipping :: IsStream t => ZipSerialM m a -> t m a
1041−zipping = asZipStream
1023+zipping = zipSerially
1042
1024
1043−-- | Fix the type of a polymorphic stream as 'ZipParallelM'.
1025+-- | Fix the type of a polymorphic stream as 'ZipAsyncM'.
1044--
1026--
1045-- @since 0.2.0
1027-- @since 0.2.0
1046−asZipParallel :: IsStream t => ZipParallelM m a -> t m a
1028+zipAsyncly :: IsStream t => ZipAsyncM m a -> t m a
1047−asZipParallel = adapt
1029+zipAsyncly = adapt
1048
1030
1049−-- | Same as 'asZipParallel'.
1031+-- | Same as 'zipAsyncly'.
1050--
1032--
1051-- @since 0.1.0
1033-- @since 0.1.0
1052−{-# DEPRECATED zippingAsync "Please use asZipParallel instead." #-}
1034+{-# DEPRECATED zippingAsync "Please use zipAsyncly instead." #-}
1053−zippingAsync :: IsStream t => ZipParallelM m a -> t m a
1035+zippingAsync :: IsStream t => ZipAsyncM m a -> t m a
1054−zippingAsync = asZipParallel
1036+zippingAsync = zipAsyncly
1055
1037
1056-------------------------------------------------------------------------------
1038-------------------------------------------------------------------------------
1057-- Running Streams, convenience functions specialized to types
1039-- Running Streams, convenience functions specialized to types
@@ -1061,71 +1043,71 @@ zippingAsync = asZipParallel
1061--
1043--
1062-- @since 0.1.0
1044-- @since 0.1.0
1063{-# DEPRECATED runStreamT "Please use runStream instead." #-}
1045{-# DEPRECATED runStreamT "Please use runStream instead." #-}
1064−runStreamT :: Monad m => StreamT m a -> m ()
1046+runStreamT :: Monad m => SerialT m a -> m ()
1065runStreamT = runStream
1047runStreamT = runStream
1066
1048
1067−-- | Same as @runStream . asCostream@.
1049+-- | Same as @runStream . wSerially@.
1068--
1050--
1069-- @since 0.1.0
1051-- @since 0.1.0
1070{-# DEPRECATED runInterleavedT "Please use 'runStream . interleaving' instead." #-}
1052{-# DEPRECATED runInterleavedT "Please use 'runStream . interleaving' instead." #-}
1071runInterleavedT :: Monad m => InterleavedT m a -> m ()
1053runInterleavedT :: Monad m => InterleavedT m a -> m ()
1072−runInterleavedT = runStream . asCostream
1054+runInterleavedT = runStream . wSerially
1073
1055
1074−-- | Same as @runStream . asParAhead@.
1056+-- | Same as @runStream . asyncly@.
1075--
1057--
1076-- @since 0.1.0
1058-- @since 0.1.0
1077−{-# DEPRECATED runAsyncT "Please use 'runStream . asParAhead' instead." #-}
1059+{-# DEPRECATED runAsyncT "Please use 'runStream . asyncly' instead." #-}
1078−runAsyncT :: Monad m => ParAheadT m a -> m ()
1060+runAsyncT :: Monad m => AsyncT m a -> m ()
1079−runAsyncT = runStream . asParAhead
1061+runAsyncT = runStream . asyncly
1080
1062
1081−-- | Same as @runStream . asParallel@.
1063+-- | Same as @runStream . parallely@.
1082--
1064--
1083-- @since 0.1.0
1065-- @since 0.1.0
1084−{-# DEPRECATED runParallelT "Please use 'runStream . asParallel' instead." #-}
1066+{-# DEPRECATED runParallelT "Please use 'runStream . parallely' instead." #-}
1085runParallelT :: Monad m => ParallelT m a -> m ()
1067runParallelT :: Monad m => ParallelT m a -> m ()
1086−runParallelT = runStream . asParallel
1068+runParallelT = runStream . parallely
1087
1069
1088-- | Same as @runStream . zipping@.
1070-- | Same as @runStream . zipping@.
1089--
1071--
1090-- @since 0.1.0
1072-- @since 0.1.0
1091−{-# DEPRECATED runZipStream "Please use 'runStream . asZipStream instead." #-}
1073+{-# DEPRECATED runZipStream "Please use 'runStream . zipSerially instead." #-}
1092−runZipStream :: Monad m => ZipStreamM m a -> m ()
1074+runZipStream :: Monad m => ZipSerialM m a -> m ()
1093−runZipStream = runStream . asZipStream
1075+runZipStream = runStream . zipSerially
1094
1076
1095-- | Same as @runStream . zippingAsync@.
1077-- | Same as @runStream . zippingAsync@.
1096--
1078--
1097-- @since 0.1.0
1079-- @since 0.1.0
1098−{-# DEPRECATED runZipAsync "Please use 'runStream . asZipParallel instead." #-}
1080+{-# DEPRECATED runZipAsync "Please use 'runStream . zipAsyncly instead." #-}
1099−runZipAsync :: Monad m => ZipParallelM m a -> m ()
1081+runZipAsync :: Monad m => ZipAsyncM m a -> m ()
1100−runZipAsync = runStream . asZipParallel
1082+runZipAsync = runStream . zipAsyncly
1101
1083
1102------------------------------------------------------------------------------
1084------------------------------------------------------------------------------
1103-- IO Streams
1085-- IO Streams
1104------------------------------------------------------------------------------
1086------------------------------------------------------------------------------
1105
1087
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
1107-- for more details.
1089-- for more details.
1108--
1090--
1109-- @since 0.2.0
1091-- @since 0.2.0
1110−type Stream a = StreamT IO a
1092+type Serial a = SerialT IO a
1111
1093
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'
1113-- documentation for more details.
1095-- documentation for more details.
1114--
1096--
1115-- @since 0.2.0
1097-- @since 0.2.0
1116−type Costream a = CostreamT IO a
1098+type WSerial a = WSerialT IO a
1117
1099
1118-- | A demand driven left biased parallely composing IO stream of elements of
1100-- | 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.
1120--
1102--
1121-- @since 0.2.0
1103-- @since 0.2.0
1122−type ParAhead a = ParAheadT IO a
1104+type Async a = AsyncT IO a
1123
1105
1124-- | A round robin parallely composing IO stream of elements of type @a@.
1106-- | 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.
1126--
1108--
1127-- @since 0.2.0
1109-- @since 0.2.0
1128−type CoparAhead a = CoparAheadT IO a
1110+type WAsync a = WAsyncT IO a
1129
1111
1130-- | A parallely composing IO stream of elements of type @a@.
1112-- | A parallely composing IO stream of elements of type @a@.
1131-- See 'ParallelT' documentation for more details.
1113-- See 'ParallelT' documentation for more details.
@@ -1136,12 +1118,12 @@ type Parallel a = ParallelT IO a
1136-- | An IO stream whose applicative instance zips streams serially.
1118-- | An IO stream whose applicative instance zips streams serially.
1137--
1119--
1138-- @since 0.2.0
1120-- @since 0.2.0
1139−type ZipStream a = ZipStreamM IO a
1121+type ZipSerial a = ZipSerialM IO a
1140
1122
1141−-- | An IO stream whose applicative instance zips streams asCoparAhead.
1123+-- | An IO stream whose applicative instance zips streams wAsyncly.
1142--
1124--
1143-- @since 0.2.0
1125-- @since 0.2.0
1144−type ZipParallel a = ZipParallelM IO a
1126+type ZipAsync a = ZipAsyncM IO a
1145
1127
1146------------------------------------------------------------------------------
1128------------------------------------------------------------------------------
1147-- Fold Utilities
1129-- Fold Utilities
@@ -1150,7 +1132,7 @@ type ZipParallel a = ZipParallelM IO a
1150-- | A variant of 'Data.Foldable.fold' that allows you to fold a 'Foldable'
1132-- | A variant of 'Data.Foldable.fold' that allows you to fold a 'Foldable'
1151-- container of streams using the specified stream sum operation.
1133-- container of streams using the specified stream sum operation.
1152--
1134--
1153−-- @foldWith 'parAhead' $ map return [1..3]@
1135+-- @foldWith 'async' $ map return [1..3]@
1154--
1136--
1155-- @since 0.1.0
1137-- @since 0.1.0
1156{-# INLINABLE foldWith #-}
1138{-# INLINABLE foldWith #-}
@@ -1162,7 +1144,7 @@ foldWith f = foldr f nil
1162-- on a 'Foldable' container and then fold it using the specified stream sum
1144-- on a 'Foldable' container and then fold it using the specified stream sum
1163-- operation.
1145-- operation.
1164--
1146--
1165−-- @foldMapWith 'parAhead' return [1..3]@
1147+-- @foldMapWith 'async' return [1..3]@
1166--
1148--
1167-- @since 0.1.0
1149-- @since 0.1.0
1168{-# INLINABLE foldMapWith #-}
1150{-# INLINABLE foldMapWith #-}
src/Streamly/Tutorial.hs+301−204
@@ -37,6 +37,9 @@ module Streamly.Tutorial
37 -- * Streams
37 -- * Streams
38 -- $streams
38 -- $streams
39
39
40+ -- * Flavors of Streams
41+ -- $flavors
42+
40 -- * Generating Streams
43 -- * Generating Streams
41 -- $generating
44 -- $generating
42
45
@@ -51,16 +54,19 @@ module Streamly.Tutorial
51 -- ** Semigroup Style
54 -- ** Semigroup Style
52 -- $semigroup
55 -- $semigroup
53
56
54− -- *** Serial Depth First Composition ('Stream')
57+ -- *** Deep Serial Composition ('Serial')
55 -- $serial
58 -- $serial
56
59
57− -- *** Serial Breadth First Composition ('Costream')
60+ -- *** Wide Serial Composition ('WSerial')
58 -- $interleaved
61 -- $interleaved
59
62
60− -- *** Concurrent Depth First Composition ('ParAhead')
63+ -- *** Deep Asynchronous Composition ('Async')
61− -- $parAhead
64+ -- $async
65+
66+ -- *** Wide Asynchronous Composition ('WAsync')
67+ -- $wasync
62
68
63− -- *** Concurrent Breadth First Composition ('CoParAhead')
69+ -- *** Parallel Asynchronous Composition ('Parallel')
64 -- $parallel
70 -- $parallel
65
71
66 -- *** Custom composition
72 -- *** Custom composition
@@ -75,17 +81,20 @@ module Streamly.Tutorial
75 -- ** Monad
81 -- ** Monad
76 -- $monad
82 -- $monad
77
83
78− -- *** Serial Depth First Nesting ('Stream')
84+ -- *** Deep Serial Nesting ('Serial')
79 -- $regularSerial
85 -- $regularSerial
80
86
81− -- *** Serial Breadth First Nesting ('Costream')
87+ -- *** Wide Serial Nesting ('WSerial')
82 -- $interleavedNesting
88 -- $interleavedNesting
83
89
84− -- *** Concurrent Depth First Nesting ('ParAhead')
90+ -- *** Deep Asynchronous Nesting ('Async')
85 -- $concurrentNesting
91 -- $concurrentNesting
86
92
87− -- *** Concurrent Breadth First Nesting ('CoparAhead')
93+ -- *** Wide Asynchronous Nesting ('WAsync')
88− -- $fairlyConcurrentNesting
94+ -- $wasyncNesting
95+
96+ -- *** Parallel Asynchronous Nesting ('Parallel')
97+ -- $parallelNesting
89
98
90 -- *** Exercise
99 -- *** Exercise
91 -- $monadExercise
100 -- $monadExercise
@@ -105,9 +114,6 @@ module Streamly.Tutorial
105 -- ** Parallel Zipping
114 -- ** Parallel Zipping
106 -- $parallelzip
115 -- $parallelzip
107
116
108− -- * Summary of Compositions
109− -- $compositionSummary
110−
111 -- * Monad transformers
117 -- * Monad transformers
112 -- $monadtransformers
118 -- $monadtransformers
113
119
@@ -149,47 +155,90 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
149-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
155-- concurrent list transformer. In contrast to the "Prelude" lists, merging or
150-- appending streams of arbitrary length is scalable and inexpensive.
156-- appending streams of arbitrary length is scalable and inexpensive.
151--
157--
152−-- The basic stream type is 'Stream', it represents a sequence of IO actions,
158+-- The basic stream type is 'Serial', 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
159+-- and is a 'Monad'. The 'Serial' monad is almost a drop in replacement for
166−-- monad is a special case of the 'Stream' monad; IO monad represents a single
160+-- the 'IO' monad, IO monad is a special case of the 'Serial' monad; IO monad
167−-- IO action whereas the 'Stream' monad represents a sequence of IO actions.
161+-- represents a single IO action whereas the 'Serial' monad represents a series
168−-- The only change you need to make to go from 'IO' to 'Stream' is to use
162+-- of IO actions. The only change you need to make to go from 'IO' to 'Serial'
169−-- 'runStream' to run the monad and to prefix the IO actions with 'once'. You
163+-- is to use 'runStream' to run the monad and to prefix the IO actions with
170−-- can also use 'liftIO' instead of 'once'. In fact, if you use liftIO you can
164+-- either 'once' or 'liftIO'. If you use liftIO you can switch from 'Serial'
171−-- switch from 'Stream' to IO monad by simply removing the 'runStream'
165+-- to IO monad by simply removing the 'runStream' function; no other changes
172−-- function; no other changes are needed unless you have used some stream
166+-- are needed unless you have used some stream specific composition or
173−-- specific composition or combinators.
167+-- combinators.
174−--
168+--
175−-- Similarly, the 'Stream' type is almost a drop in replacement for pure lists,
169+-- Similarly, the 'Serial' type is almost a drop in replacement for pure lists,
176-- pure lists are a special case of monadic streams. If you use 'nil' in place
170-- 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
178-- only difference is that the elements must be monadic type and to operate on
172-- only difference is that the elements must be monadic type and to operate on
179-- the streams we must use the corresponding functions from "Streamly.Prelude"
173-- the streams we must use the corresponding functions from "Streamly.Prelude"
180-- instead of using the base "Prelude".
174-- instead of using the base "Prelude".
181
175
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+
182-- $monadtransformers
231-- $monadtransformers
183--
232--
184-- To represent streams in an arbitrary monad use the more general monad
233-- To represent streams in an arbitrary monad use the more general monad
185-- transformer types for example the monad transformer type corresponding to
234-- transformer types for example the monad transformer type corresponding to
186−-- the 'Stream' type is 'StreamT'. @StreamT m a@ represents a stream of values
235+-- the 'Serial' type is 'SerialT'. @SerialT m a@ represents a stream of values
187−-- of type 'a' in some underlying monad 'm'. For example, @StreamT IO Int@ is a
236+-- of type 'a' in some underlying monad 'm'. For example, @SerialT IO Int@ is a
188−-- stream of 'Int' in 'IO' monad. In fact, the type 'Stream' is a synonym for
237+-- stream of 'Int' in 'IO' monad. In fact, the type 'Serial' is a synonym for
189−-- @StreamT IO@.
238+-- @SerialT IO@.
190--
239--
191-- Similarly we have monad transformer types for other stream types as well viz.
240-- Similarly we have monad transformer types for other stream types as well viz.
192−-- 'CostreamT', 'ParAheadT' and 'CoparAheadT'.
241+-- 'WSerialT', 'AsyncT', 'WAsyncT' and 'ParallelT'.
193--
242--
194-- To lift a value from an underlying monad in a monad transformer stack into a
243-- To lift a value from an underlying monad in a monad transformer stack into a
195-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
244-- singleton stream use 'lift' and to lift from an IO action use 'liftIO'.
@@ -307,17 +356,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
307-- We can combine two streams into a single stream using semigroup composition
356-- We can combine two streams into a single stream using semigroup composition
308-- operation '<>'. Streams can be combined in many different ways as described
357-- operation '<>'. Streams can be combined in many different ways as described
309-- in the following sections, the '<>' operation behaves differently depending
358-- in the following sections, the '<>' operation behaves differently depending
310−-- on the stream type in effect. Streamly streams can be of many
359+-- on the stream type in effect. The stream type and therefore the composition
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.
360+-- style can be changed at any point using one of the type combinators as
361+-- discussed earlier.
319−--
362+--
320−-- To illustrate the concurrent vs serial composition aspects, we will use the
363+-- To illustrate concurrent vs serial composition aspects, we will use the
321-- following @delay@ function to introduce a delay specified in seconds.
364-- following @delay@ function to introduce a delay specified in seconds.
322--
365--
323-- @
366-- @
@@ -334,11 +377,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
334
377
335-- $serial
378-- $serial
336--
379--
337−-- The 'Semigroup' operation '<>' of the 'Stream' type combines the two streams
380+-- The 'Semigroup' operation '<>' of the 'Serial' type combines the two streams
338−-- in a /serial depth first/ manner. We use the 'asStream' type combinator to
381+-- in a /serial depth first/ manner. We use the 'serially' type combinator to
339−-- effect 'Stream' style of composition. We can also use an explicit 'Stream'
382+-- effect 'Serial' style of composition. We can also use an explicit 'Serial'
340-- type annotation for the stream to acheive the same effect. However, since
383-- 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
342-- combinator, we can omit using an explicit combinator or type annotation for
385-- combinator, we can omit using an explicit combinator or type annotation for
343-- this style of composition.
386-- this style of composition.
344--
387--
@@ -362,7 +405,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
362--
405--
363-- All actions in both the streams are performed serially in the same thread.
406-- All actions in both the streams are performed serially in the same thread.
364-- In the following example we can see that all actions are performed in the
407-- 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:
366--
409--
367-- @
410-- @
368-- main = 'runStream' $ delay 3 <> delay 2 <> delay 1
411-- main = 'runStream' $ delay 3 <> delay 2 <> delay 1
@@ -373,20 +416,20 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
373-- ThreadId 36: Delay 1
416-- ThreadId 36: Delay 1
374-- @
417-- @
375--
418--
376−-- The polymorphic version of the 'Stream' binary operation '<>' is called
419+-- The polymorphic version of the binary operation '<>' of the 'Serial' type is
377−-- 'splice'. We can use 'splice' to join streams in a sequential manner
420+-- 'serial'. We can use 'serial' to join streams in a sequential manner
378-- irrespective of the type of stream:
421-- irrespective of the type of stream:
379--
422--
380-- @
423-- @
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)
382-- @
425-- @
383
426
384-- $interleaved
427-- $interleaved
385--
428--
386−-- The 'Semigroup' operation '<>' of the 'Costream' type combines the two
429+-- The 'Semigroup' operation '<>' of the 'WSerial' type combines the two
387−-- streams in a /serial breadth first/ manner. We use the 'asCostream' type
430+-- streams in a /serial breadth first/ manner. We use the 'wSerially' type
388−-- combinator to effect 'Costream' style of composition. We can also use the
431+-- combinator to effect 'WSerial' style of composition. We can also use the
389−-- 'Costream' type annotation for the stream to acheive the same effect.
432+-- 'WSerial' type annotation for the stream to acheive the same effect.
390--
433--
391-- When two streams with multiple elements are combined in this manner, we
434-- When two streams with multiple elements are combined in this manner, we
392-- traverse all the streams in a breadth first manner i.e. one action from each
435-- 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))
395-- The following example prints the sequence 1, 3, 2, 4
438-- The following example prints the sequence 1, 3, 2, 4
396--
439--
397-- @
440-- @
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)
399-- @
442-- @
400-- @
443-- @
401-- 1
444-- 1
@@ -407,10 +450,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
407-- Even though the monadic actions of the two streams are performed in an
450-- Even though the monadic actions of the two streams are performed in an
408-- interleaved manner they are all performed serially in the same thread. In
451-- interleaved manner they are all performed serially in the same thread. In
409-- the following example we can see that all actions are performed in the same
452-- 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:
411--
454--
412-- @
455-- @
413−-- main = 'runStream' . 'asCostream' $ delay 3 <> delay 2 <> delay 1
456+-- main = 'runStream' . 'wSerially' $ delay 3 <> delay 2 <> delay 1
414-- @
457-- @
415-- @
458-- @
416-- ThreadId 36: Delay 3
459-- ThreadId 36: Delay 3
@@ -418,13 +461,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
418-- ThreadId 36: Delay 1
461-- ThreadId 36: Delay 1
419-- @
462-- @
420--
463--
421−-- The polymorphic version of the 'Costream' binary operation '<>' is called
464+-- The polymorphic version of the 'WSerial' binary operation '<>' is called
422−-- 'cosplice'. We can use 'cosplice' to join streams in an interleaved manner
465+-- 'wSerial'. We can use 'wSerial' to join streams in an interleaved manner
423−-- irrespective of the type, notice that we have not used the 'asCostream'
466+-- irrespective of the type, notice that we have not used the 'wSerially'
424-- combinator in the following example:
467-- combinator in the following example:
425--
468--
426-- @
469-- @
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)
428-- @
471-- @
429-- @
472-- @
430-- 1
473-- 1
@@ -436,16 +479,16 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
436-- Note that this composition cannot be used to fold infinite number of streams
479-- Note that this composition cannot be used to fold infinite number of streams
437-- since it requires preserving the state until a stream is finished.
480-- since it requires preserving the state until a stream is finished.
438
481
439−-- $parAhead
482+-- $async
440--
483--
441−-- The 'Semigroup' operation '<>' of the 'ParAhead' type combines the two
484+-- The 'Semigroup' operation '<>' of the 'Async' type combines the two
442-- streams in a depth first manner with parallel look ahead. We use the
485-- streams in a depth first manner with parallel look ahead. We use the
443−-- 'asParAhead' type combinator to effect 'ParAhead' style of composition. We
486+-- 'asyncly' type combinator to effect 'Async' style of composition. We
444−-- can also use the 'ParAhead' type annotation for the stream type to acheive
487+-- can also use the 'Async' type annotation for the stream type to acheive
445-- the same effect.
488-- the same effect.
446--
489--
447-- When two streams with multiple elements are combined in this manner, the
490-- 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
449-- can execute the next stream concurrently and return the results from it
492-- can execute the next stream concurrently and return the results from it
450-- as they arrive i.e. the results from the next stream may be yielded even
493-- as they arrive i.e. the results from the next stream may be yielded even
451-- before the results from the first stream. Concurrent execution of the next
494-- before the results from the first stream. Concurrent execution of the next
@@ -456,7 +499,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
456-- therefore the first stream is completely exhausted before the second.
499-- therefore the first stream is completely exhausted before the second.
457--
500--
458-- @
501-- @
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)
460-- @
503-- @
461-- @
504-- @
462-- 1
505-- 1
@@ -470,7 +513,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
470-- and 3 would be yielded first and then 2 and 4 would be yielded.
513-- and 3 would be yielded first and then 2 and 4 would be yielded.
471--
514--
472-- @
515-- @
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)
474-- where p n = threadDelay 1000000 >> print n
517-- where p n = threadDelay 1000000 >> print n
475-- @
518-- @
476-- @
519-- @
@@ -482,10 +525,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
482--
525--
483-- In the following example we can see that new threads are started when a
526-- In the following example we can see that new threads are started when a
484-- computation blocks. Notice that the output from the stream with the
527-- 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:
486--
530--
487-- @
531-- @
488−-- main = 'runStream' . 'asParAhead' $ delay 3 '<>' delay 2 '<>' delay 1
532+-- main = 'runStream' . 'asyncly' $ delay 3 '<>' delay 2 '<>' delay 1
489-- @
533-- @
490-- @
534-- @
491-- ThreadId 42: Delay 1
535-- ThreadId 42: Delay 1
@@ -494,7 +538,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
494-- @
538-- @
495--
539--
496-- When we have a tree of computations composed using this style, the tree is
540-- 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
498-- that here we can move on to executing the next stream if a stream blocks.
542-- that here we can move on to executing the next stream if a stream blocks.
499-- However, we will not start new threads if we have sufficient output to
543-- However, we will not start new threads if we have sufficient output to
500-- saturate the consumer. This is why we call it left-biased demand driven or
544-- 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))
504-- second as all of the actions are concurrent.
548-- second as all of the actions are concurrent.
505--
549--
506-- @
550-- @
507−-- main = 'runStream' . 'asParAhead' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
551+-- main = 'runStream' . 'asyncly' $ (delay 1 <> delay 2) <> (delay 3 <> delay 4)
508-- @
552-- @
509-- @
553-- @
510-- 1
554-- 1
@@ -521,7 +565,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
521-- even if none of them blocks:
565-- even if none of them blocks:
522--
566--
523-- @
567-- @
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)
525-- where traced m = S.'once' (myThreadId >>= print) >> return m
569-- where traced m = S.'once' (myThreadId >>= print) >> return m
526-- @
570-- @
527-- @
571-- @
@@ -533,13 +577,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
533-- Note that the order of printing in the above examples may change due to
577-- Note that the order of printing in the above examples may change due to
534-- variations in scheduling latencies for concurrent threads.
578-- variations in scheduling latencies for concurrent threads.
535--
579--
536−-- The polymorphic version of the 'ParAhead' binary operation '<>' is called
580+-- The polymorphic version of the 'Async' binary operation '<>' is called
537−-- 'parAhead'. We can use 'parAhead' to join streams in a left biased
581+-- 'async'. We can use 'async' to join streams in a left biased
538-- adaptively concurrent manner irrespective of the type, notice that we have
582-- 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:
540--
584--
541-- @
585-- @
542−-- main = 'runStream' $ delay 3 \`parAhead` delay 2 \`parAhead` delay 1
586+-- main = 'runStream' $ delay 3 \`async` delay 2 \`async` delay 1
543-- @
587-- @
544-- @
588-- @
545-- ThreadId 42: Delay 1
589-- ThreadId 42: Delay 1
@@ -555,27 +599,80 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
555-- all computations at once for any reason 'Parallel' style must be used
599-- all computations at once for any reason 'Parallel' style must be used
556-- instead.
600-- instead.
557--
601--
558−-- 'ParAhead' style should be preferred over 'CoparAhead' unless you really
602+-- 'Async' style should be preferred over 'Parallel' or 'WAsync' unless you
559−-- need 'CoparAhead'. It utilizes the resources optimally. It should be used when
603+-- really need those. It utilizes the resources optimally. It should be used
560−-- we know that the computations can run in parallel but we do not care if they
604+-- when we know that the computations can run in parallel but we do not care if
561−-- actually run in parallel or not, that decision can be left to the scheduler
605+-- they actually run in parallel or not, that decision can be left to the
562−-- based on demand. Also, note that this operator can be used to fold infinite
606+-- scheduler based on demand. Also, note that this operator can be used to fold
563−-- number of streams in contrast to the 'CoparAhead' style, because it does not
607+-- infinite number of streams in contrast to the 'Parallel' or 'WAsync' styles,
564−-- require us to run all of them at the same time in a fair manner.
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+--
565
660
566-- $parallel
661-- $parallel
567--
662--
568-- The 'Semigroup' operation '<>' of the 'Parallel' type combines the two
663-- The 'Semigroup' operation '<>' of the 'Parallel' type combines the two
569-- streams in a fairly concurrent manner with round robin scheduling. We use
664-- streams in a fairly concurrent manner with round robin scheduling. We use
570−-- the 'parallel' type combinator to effect 'Parallel' style of composition. We
665+-- the 'parallely' type combinator to effect 'Parallel' style of composition.
571−-- can also use the 'Parallel' type annotation for the stream type to acheive
666+-- We can also use the 'Parallel' type annotation for the stream type to
572−-- the same effect.
667+-- acheive the same effect.
573--
668--
574-- When two streams with multiple elements are combined in this manner, the
669-- When two streams with multiple elements are combined in this manner, the
575-- monadic actions in both the streams are performed concurrently with a fair
670-- monadic actions in both the streams are performed concurrently with a fair
576-- round robin scheduling. The outputs are yielded in the order in which the
671-- 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
672+-- actions complete. This is pretty similar to the 'WAsync' type, the
578−-- 'Costream' style serial composition.
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.
579--
676--
580-- The following example sends a query to all the three search engines in
677-- The following example sends a query to all the three search engines in
581-- parallel and prints the name of the search engines in the order in which the
678-- 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))
586-- import qualified Streamly.Prelude as S
683-- import qualified Streamly.Prelude as S
587-- import Network.HTTP.Simple
684-- import Network.HTTP.Simple
588--
685--
589−-- main = 'runStream' . 'asParallel' $ google \<> bing \<> duckduckgo
686+-- main = 'runStream' . 'parallely' $ google \<> bing \<> duckduckgo
590-- where
687-- where
591-- google = get "https://www.google.com/search?q=haskell"
688-- google = get "https://www.google.com/search?q=haskell"
592-- bing = get "https://www.bing.com/search?q=haskell"
689-- bing = get "https://www.bing.com/search?q=haskell"
@@ -594,27 +691,13 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
594-- get s = S.'once' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
691-- get s = S.'once' (httpNoBody (parseRequest_ s) >> putStrLn (show s))
595-- @
692-- @
596--
693--
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
694+-- The polymorphic version of the binary operation '<>' of the 'Parallel' type
612−-- 'coparAhead'. We can use 'coparAhead' to join streams in a fairly
695+-- is 'parallel'. We can use 'parallel' to join streams in a fairly concurrent
613−-- concurrent manner irrespective of the type, notice that we have
696+-- manner irrespective of the type, notice that we have not used the
614−-- not used the 'asCoparAhead' combinator in the following example:
697+-- 'parallely' combinator in the following example:
615--
698--
616-- @
699-- @
617−-- main = 'runStream' $ delay 3 \`coparAhead` delay 2 \`coparAhead` delay 1
700+-- main = 'runStream' $ delay 3 \`parallel` delay 2 \`wAsync` delay 1
618-- @
701-- @
619-- @
702-- @
620-- ThreadId 42: Delay 1
703-- ThreadId 42: Delay 1
@@ -628,7 +711,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
628
711
629-- $custom
712-- $custom
630--
713--
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
632-- stream computations. We can then use 'uncons' to explore the streams
715-- stream computations. We can then use 'uncons' to explore the streams
633-- arbitrarily and then recompose individual elements to create a new stream.
716-- arbitrarily and then recompose individual elements to create a new stream.
634-- This way we can dynamically decide which stream to explore at any given
717-- This way we can dynamically decide which stream to explore at any given
@@ -660,10 +743,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
660-- import Control.Concurrent
743-- import Control.Concurrent
661--
744--
662-- main = do
745-- main = do
663−-- 'runStream' $ 'asParAhead' $ foldMap delay [1..10]
746+-- 'runStream' $ 'asyncly' $ foldMap delay [1..10]
664−-- 'runStream' $ 'foldWith' 'parAhead' (map delay [1..10])
747+-- 'runStream' $ 'foldWith' 'async' (map delay [1..10])
665−-- 'runStream' $ 'foldMapWith' 'parAhead' delay [1..10]
748+-- 'runStream' $ 'foldMapWith' 'async' delay [1..10]
666−-- 'runStream' $ 'forEachWith' 'parAhead' [1..10] delay
749+-- 'runStream' $ 'forEachWith' 'async' [1..10] delay
667-- where delay n = S.'once' $ threadDelay (n * 1000000) >> print n
750-- where delay n = S.'once' $ threadDelay (n * 1000000) >> print n
668-- @
751-- @
669
752
@@ -688,18 +771,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
688-- element in the first stream and for each element in the second stream
771-- element in the first stream and for each element in the second stream
689-- execute the body of the loop.
772-- execute the body of the loop.
690--
773--
691−-- The 'Monad' instances of 'Stream', 'Costream', 'ParAhead' and 'CoparAhead'
774+-- The 'Monad' instances of 'Serial', 'WSerial', 'Async' and 'WAsync'
692-- stream types support different flavors of nested looping. In other words,
775-- stream types support different flavors of nested looping. In other words,
693-- they are all variants of list transformer. The nesting behavior of these
776-- 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
695-- the previous section.
778-- the previous section.
696--
779--
697
780
698-- $regularSerial
781-- $regularSerial
699--
782--
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
701-- transformer. This is the default when we do not use an explicit type
784-- 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
703-- this style of composition. We will see how this style of composition works
786-- this style of composition. We will see how this style of composition works
704-- in the following examples.
787-- in the following examples.
705--
788--
@@ -722,7 +805,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
722-- ThreadId 30: Delay 1
805-- ThreadId 30: Delay 1
723-- @
806-- @
724--
807--
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
726-- times, once for each value of @x@ drawn from the stream. All the three
809-- times, once for each value of @x@ drawn from the stream. All the three
727-- iterations are serial and run in the same thread one after another. In
810-- iterations are serial and run in the same thread one after another. In
728-- imperative terms this is equivalent to a @for@ loop with three iterations.
811-- imperative terms this is equivalent to a @for@ loop with three iterations.
@@ -758,27 +841,27 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
758-- (2,4)
841-- (2,4)
759-- @
842-- @
760--
843--
761−-- Notice that this is analogous to merging streams of type 'Stream' or merging
844+-- Notice that this is analogous to merging streams of type 'Serial' or merging
762−-- streams using 'splice'.
845+-- streams using 'serial'.
763
846
764-- $concurrentNesting
847-- $concurrentNesting
765--
848--
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
767-- loop concurrently. Concurrency is demand driven i.e. more concurrent
850-- loop concurrently. Concurrency is demand driven i.e. more concurrent
768-- iterations are started only if the previous iterations are not able to
851-- iterations are started only if the previous iterations are not able to
769-- produce enough output for the consumer of the output stream. This works
852-- 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.
853+-- exactly the same way as the merging of two streams 'asyncly' works.
771−-- This is the concurrent analogue of 'Stream' style monadic composition.
854+-- This is the concurrent analogue of 'Serial' style monadic composition.
772--
855--
773−-- The 'asParAhead' type combinator can be used to switch to this
856+-- The 'asyncly' type combinator can be used to switch to this style of
774−-- style of composition. Alternatively, a type annotation can be used to
857+-- composition. Alternatively, a type annotation can be used to specify the
775−-- specify the type of the stream as 'ParAhead'.
858+-- type of the stream as 'Async'.
776--
859--
777-- @
860-- @
778-- import "Streamly"
861-- import "Streamly"
779-- import "Streamly.Prelude"
862-- import "Streamly.Prelude"
780--
863--
781−-- main = 'runStream' . 'asParAhead' $ do
864+-- main = 'runStream' . 'asyncly' $ do
782-- x <- 'fromFoldable' [3,2,1]
865-- x <- 'fromFoldable' [3,2,1]
783-- delay x
866-- delay x
784-- @
867-- @
@@ -788,24 +871,24 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
788-- ThreadId 38: Delay 3
871-- ThreadId 38: Delay 3
789-- @
872-- @
790--
873--
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
792-- times, once for each value of @x@. All the three iterations are concurrent
875-- times, once for each value of @x@. All the three iterations are concurrent
793-- and run in different threads. The iteration with least delay finishes first.
876-- and run in different threads. The iteration with least delay finishes first.
794-- When compared to imperative programming, this can be viewed as a @for@ loop
877-- When compared to imperative programming, this can be viewed as a @for@ loop
795-- with three concurrent iterations.
878-- with three concurrent iterations.
796--
879--
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.
798-- When multiple streams are composed using this style, the iterations are
881-- 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
800-- executed before we proceed to the next iteration at higher level. However,
883-- executed before we proceed to the next iteration at higher level. However,
801−-- unlike 'Stream' more than one iterations may be started concurrently based
884+-- unlike 'Serial' more than one iterations may be started concurrently based
802−-- on the demand from the consumer.
885+-- on the demand from the consumer of the stream.
803--
886--
804-- @
887-- @
805-- import "Streamly"
888-- import "Streamly"
806-- import qualified "Streamly.Prelude" as S
889-- import qualified "Streamly.Prelude" as S
807--
890--
808−-- main = 'runStream' . 'asParAhead' $ do
891+-- main = 'runStream' . 'asyncly' $ do
809-- x <- S.'fromFoldable' [1,2]
892-- x <- S.'fromFoldable' [1,2]
810-- y <- S.'fromFoldable' [3,4]
893-- y <- S.'fromFoldable' [3,4]
811-- S.'once' $ putStrLn $ show (x, y)
894-- S.'once' $ putStrLn $ show (x, y)
@@ -819,18 +902,18 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
819
902
820-- $interleavedNesting
903-- $interleavedNesting
821--
904--
822−-- The 'Monad' composition of 'Costream' type interleaves the iterations of
905+-- The 'Monad' composition of 'WSerial' type interleaves the iterations of
823-- outer and inner loops in a nested loop composition. This works exactly the
906-- 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
907+-- same way as the merging of two streams in 'wSerially' fashion works. The
825−-- 'asCostream' type combinator can be used to switch to this style of
908+-- 'wSerially' type combinator can be used to switch to this style of
826-- composition. Alternatively, a type annotation can be used to specify the
909-- 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'.
828--
911--
829-- @
912-- @
830-- import "Streamly"
913-- import "Streamly"
831-- import qualified "Streamly.Prelude" as S
914-- import qualified "Streamly.Prelude" as S
832--
915--
833−-- main = 'runStream' . 'asCostream' $ do
916+-- main = 'runStream' . 'wSerially' $ do
834-- x <- S.'fromFoldable' [1,2]
917-- x <- S.'fromFoldable' [1,2]
835-- y <- S.'fromFoldable' [3,4]
918-- y <- S.'fromFoldable' [3,4]
836-- S.once $ putStrLn $ show (x, y)
919-- S.once $ putStrLn $ show (x, y)
@@ -843,14 +926,42 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
843-- @
926-- @
844--
927--
845
928
846−-- $fairlyConcurrentNesting
929+-- $wasyncNesting
847--
930--
848−-- The 'Monad' composition of 'Parallel' type starts all the iterations of a
931+-- Just like 'Async' the 'Monad' composition of 'WAsync' runs the iterations of
849−-- loop concurrently instead of demand driven as in the case of 'ParAhead'.
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
850−-- This works exactly the same way as the merging streams 'parallely' works.
962+-- the merging of streams 'parallely' works. The 'parallely' type combinator
851−-- The 'parallely' type combinator can be used to switch to this style of
963+-- can be used to switch to this style of composition. Alternatively, a type
852−-- composition. Alternatively, a type annotation can be used to specify the
853−-- type of the stream as 'Parallel'.
964+-- annotation can be used to specify the type of the stream as 'Parallel'.
854--
965--
855-- @
966-- @
856-- import "Streamly"
967-- import "Streamly"
@@ -868,7 +979,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
868
979
869-- $monadExercise
980-- $monadExercise
870--
981--
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
872-- specific monadic composition type. We use a polymorphic type with a
983-- specific monadic composition type. We use a polymorphic type with a
873-- 'IsStream' type class constraint. When running the stream we can choose the
984-- 'IsStream' type class constraint. When running the stream we can choose the
874-- specific mode of composition. For example take a look at the following code.
985-- specific mode of composition. For example take a look at the following code.
@@ -894,10 +1005,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
894-- Now we can interpret this in whatever way we want:
1005-- Now we can interpret this in whatever way we want:
895--
1006--
896-- @
1007-- @
897−-- main = 'runStream' . 'asStream' $ composed
1008+-- main = 'runStream' . 'serially' $ composed
898−-- main = 'runStream' . 'asCostream' $ composed
899−-- main = 'runStream' . 'asParAhead' $ composed
1009+-- main = 'runStream' . 'wSerially' $ composed
900−-- main = 'runStream' . 'asCoparAhead' $ composed
1010+-- main = 'runStream' . 'asyncly' $ composed
1011+-- main = 'runStream' . 'wAsyncly' $ composed
1012+-- main = 'runStream' . 'parallely' $ composed
901-- @
1013-- @
902--
1014--
903-- As an exercise try to figure out the output of this code for each mode of
1015-- 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))
922-- $applicative
1034-- $applicative
923--
1035--
924-- Applicative is precisely the same as the 'ap' operation of 'Monad'. For
1036-- 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
926-- provided.
1038-- provided.
927--
1039--
928−-- The following example uses the 'Stream' applicative, it runs all iterations
1040+-- The following example uses the 'Serial' applicative, it runs all iterations
929-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
1041-- serially and takes a total 17 seconds (1 + 3 + 4 + 2 + 3 + 4):
930--
1042--
931-- @
1043-- @
@@ -937,7 +1049,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
937-- s2 = d 3 <> d 4
1049-- s2 = d 3 <> d 4
938-- d n = delay n >> return n
1050-- d n = delay n >> return n
939--
1051--
940−-- main = (S.'toList' . 'asStream' $ (,) \<$> s1 \<*> s2) >>= print
1052+-- main = (S.'toList' . 'serially' $ (,) \<$> s1 \<*> s2) >>= print
941-- @
1053-- @
942-- @
1054-- @
943-- ThreadId 36: Delay 1
1055-- ThreadId 36: Delay 1
@@ -949,11 +1061,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
949-- [(1,3),(1,4),(2,3),(2,4)]
1061-- [(1,3),(1,4),(2,3),(2,4)]
950-- @
1062-- @
951--
1063--
952−-- Similalrly 'Costream' applicative runs the iterations in an interleaved
1064+-- Similalrly 'WSerial' applicative runs the iterations in an interleaved
953-- order but since it is serial it takes a total of 17 seconds:
1065-- order but since it is serial it takes a total of 17 seconds:
954--
1066--
955-- @
1067-- @
956−-- main = (S.'toList' . 'asCostream' $ (,) \<$> s1 \<*> s2) >>= print
1068+-- main = (S.'toList' . 'wSerially' $ (,) \<$> s1 \<*> s2) >>= print
957-- @
1069-- @
958-- @
1070-- @
959-- ThreadId 36: Delay 1
1071-- ThreadId 36: Delay 1
@@ -965,11 +1077,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
965-- [(1,3),(2,3),(1,4),(2,4)]
1077-- [(1,3),(2,3),(1,4),(2,4)]
966-- @
1078-- @
967--
1079--
968−-- 'ParAhead' can run the iterations concurrently and therefore takes a total
1080+-- 'Async' can run the iterations concurrently and therefore takes a total
969-- of 10 seconds (1 + 2 + 3 + 4):
1081-- of 10 seconds (1 + 2 + 3 + 4):
970--
1082--
971-- @
1083-- @
972−-- main = (S.'toList' . 'asParAhead' $ (,) \<$> s1 \<*> s2) >>= print
1084+-- main = (S.'toList' . 'asyncly' $ (,) \<$> s1 \<*> s2) >>= print
973-- @
1085-- @
974-- @
1086-- @
975-- ThreadId 34: Delay 1
1087-- ThreadId 34: Delay 1
@@ -981,11 +1093,11 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
981-- [(1,3),(2,3),(1,4),(2,4)]
1093-- [(1,3),(2,3),(1,4),(2,4)]
982-- @
1094-- @
983--
1095--
984−-- Similalrly 'CoparAhead' as well can run the iterations concurrently and
1096+-- Similalrly 'WAsync' as well can run the iterations concurrently and
985-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
1097-- therefore takes a total of 10 seconds (1 + 2 + 3 + 4):
986--
1098--
987-- @
1099-- @
988−-- main = (S.'toList' . 'asCoparAhead' $ (,) \<$> s1 \<*> s2) >>= print
1100+-- main = (S.'toList' . 'wAsyncly' $ (,) \<$> s1 \<*> s2) >>= print
989-- @
1101-- @
990-- @
1102-- @
991-- ThreadId 34: Delay 1
1103-- ThreadId 34: Delay 1
@@ -997,21 +1109,6 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
997-- [(1,3),(2,3),(1,4),(2,4)]
1109-- [(1,3),(2,3),(1,4),(2,4)]
998-- @
1110-- @
999
1111
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−
1015-- $zipping
1112-- $zipping
1016--
1113--
1017-- Zipping is a special transformation where the corresponding elements of two
1114-- Zipping is a special transformation where the corresponding elements of two
@@ -1023,8 +1120,8 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1023
1120
1024-- $serialzip
1121-- $serialzip
1025--
1122--
1026−-- The applicative instance of 'ZipStream' type zips streams serially.
1123+-- The applicative instance of 'ZipSerial' type zips streams serially.
1027−-- 'asZipStream' type combinator can be used to switch to serial applicative
1124+-- 'zipSerially' type combinator can be used to switch to serial applicative
1028-- zip composition:
1125-- zip composition:
1029--
1126--
1030-- @
1127-- @
@@ -1036,7 +1133,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1036-- s1 = 'streamly' $ d 1 <> d 2
1133-- s1 = 'streamly' $ d 1 <> d 2
1037-- s2 = 'streamly' $ d 3 <> d 4
1134-- s2 = 'streamly' $ d 3 <> d 4
1038--
1135--
1039−-- main = (S.'toList' . 'asZipStream' $ (,) \<$> s1 \<*> s2) >>= print
1136+-- main = (S.'toList' . 'zipSerially' $ (,) \<$> s1 \<*> s2) >>= print
1040-- @
1137-- @
1041--
1138--
1042-- This takes total 10 seconds to zip, which is (1 + 2 + 3 + 4) since
1139-- 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))
1052
1149
1053-- $parallelzip
1150-- $parallelzip
1054--
1151--
1055−-- The applicative instance of 'ZipParallel' type zips streams concurrently.
1152+-- The applicative instance of 'ZipAsync' type zips streams concurrently.
1056−-- 'asZipParallel' type combinator can be used to switch to parallel applicative
1153+-- 'zipAsyncly' type combinator can be used to switch to parallel applicative
1057-- zip composition:
1154-- zip composition:
1058--
1155--
1059--
1156--
@@ -1069,7 +1166,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1069--
1166--
1070-- main = do
1167-- main = do
1071-- hSetBuffering stdout LineBuffering
1168-- hSetBuffering stdout LineBuffering
1072−-- (S.'toList' . 'asZipParallel' $ (,) \<$> s1 \<*> s2) >>= print
1169+-- (S.'toList' . 'zipAsyncly' $ (,) \<$> s1 \<*> s2) >>= print
1073-- @
1170-- @
1074--
1171--
1075-- This takes 7 seconds to zip, which is max (1,3) + max (2,4) because 1 and 3
1172-- 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))
1093-- choose the desired type of concurrency.
1190-- choose the desired type of concurrency.
1094--
1191--
1095-- In the following example the squares of @x@ and @y@ are computed
1192-- 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
1097-- sum are computed serially because of the 'streamly' combinator. We can
1194-- sum are computed serially because of the 'streamly' combinator. We can
1098-- choose different combinators for the monadic processing and the stream
1195-- choose different combinators for the monadic processing and the stream
1099−-- generation, to control the concurrency. We can also use the 'asParAhead'
1196+-- generation, to control the concurrency. We can also use the 'asyncly'
1100−-- combinator instead of explicitly folding with 'parAhead'.
1197+-- combinator instead of explicitly folding with 'async'.
1101--
1198--
1102-- @
1199-- @
1103-- import "Streamly"
1200-- import "Streamly"
@@ -1106,17 +1203,17 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1106--
1203--
1107-- main = do
1204-- main = do
1108-- z \<- S.'toList'
1205-- z \<- S.'toList'
1109−-- $ 'asStream' -- Serial monadic processing (sqrt below)
1206+-- $ 'serially' -- Serial monadic processing (sqrt below)
1110-- $ do
1207-- $ do
1111−-- x2 \<- 'forEachWith' 'parAhead' [1..100] $ -- Concurrent @"for"@ loop
1208+-- x2 \<- 'forEachWith' 'async' [1..100] $ -- Concurrent @"for"@ loop
1112-- \\x -> return $ x * x -- body of the loop
1209-- \\x -> return $ x * x -- body of the loop
1113−-- y2 \<- 'forEachWith' 'parAhead' [1..100] $
1210+-- y2 \<- 'forEachWith' 'async' [1..100] $
1114-- \\y -> return $ y * y
1211-- \\y -> return $ y * y
1115-- return $ sqrt (x2 + y2)
1212-- return $ sqrt (x2 + y2)
1116-- print $ sum z
1213-- print $ sum z
1117-- @
1214-- @
1118--
1215--
1119−-- You can see how this directly maps to the imperative style
1216+-- We can see how this directly maps to the imperative style
1120-- <https://en.wikipedia.org/wiki/OpenMP OpenMP> model, we use combinators
1217-- <https://en.wikipedia.org/wiki/OpenMP OpenMP> model, we use combinators
1121-- and operators instead of the ugly pragmas.
1218-- and operators instead of the ugly pragmas.
1122--
1219--
@@ -1151,7 +1248,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1151--
1248--
1152-- data Event = Harm Int | Heal Int | Quit deriving (Show)
1249-- data Event = Harm Int | Heal Int | Quit deriving (Show)
1153--
1250--
1154−-- userAction :: MonadIO m => 'StreamT' m Event
1251+-- userAction :: MonadIO m => 'SerialT' m Event
1155-- userAction = cycle1 $ liftIO askUser
1252-- userAction = cycle1 $ liftIO askUser
1156-- where
1253-- where
1157-- askUser = do
1254-- askUser = do
@@ -1161,10 +1258,10 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1161-- "quit" -> return Quit
1258-- "quit" -> return Quit
1162-- _ -> putStrLn "What?" >> askUser
1259-- _ -> putStrLn "What?" >> askUser
1163--
1260--
1164−-- acidRain :: MonadIO m => 'StreamT' m Event
1261+-- acidRain :: MonadIO m => 'SerialT' m Event
1165-- acidRain = cycle1 $ liftIO (threadDelay 1000000) >> return (Harm 1)
1262-- acidRain = cycle1 $ liftIO (threadDelay 1000000) >> return (Harm 1)
1166--
1263--
1167−-- game :: ('MonadParallel' m, MonadState Int m) => 'StreamT' m ()
1264+-- game :: ('MonadAsync' m, MonadState Int m) => 'SerialT' m ()
1168-- game = do
1265-- game = do
1169-- event \<- userAction \`parallel` acidRain
1266-- event \<- userAction \`parallel` acidRain
1170-- case event of
1267-- case event of
@@ -1356,7 +1453,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift))
1356-- When it comes to concurrency, streamly can do everything that the @async@
1453-- When it comes to concurrency, streamly can do everything that the @async@
1357-- package can do and more. async provides applicative concurrency whereas
1454-- package can do and more. async provides applicative concurrency whereas
1358-- streamly provides both applicative and monadic concurrency. The
1455-- 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
1360-- comparison to transient streamly has a first class streaming interface and
1457-- comparison to transient streamly has a first class streaming interface and
1361-- is a monad transformer that can be used universally in any Haskell monad
1458-- is a monad transformer that can be used universally in any Haskell monad
1362-- transformer stack. Streamly was in fact originally inspired by the
1459-- transformer stack. Streamly was in fact originally inspired by the