@@ -48,22 +48,22 @@ module Streamly.Internal.Data.Stream.Concurrent
48 -- ** Evaluate
48 -- ** Evaluate
49 -- | Evaluates a stream concurrently using a channel.
49 -- | Evaluates a stream concurrently using a channel.
51− , evalWith
51+ , parEval
52 -- Add unfoldrM/iterateM?
52 -- Add unfoldrM/iterateM?
54 -- ** Generate
54 -- ** Generate
55 -- | Uses a single channel to evaluate all actions.
55 -- | Uses a single channel to evaluate all actions.
57− , repeatMWith
57+ , parRepeatM
58 , replicateM
58 , replicateM
59− , replicateMWith
59+ , parReplicateM
62 -- | Uses a single channel to evaluate all actions.
62 -- | Uses a single channel to evaluate all actions.
64− , mapMWith
64+ , parMapM
65 , sequence
65 , sequence
66− , sequenceWith
66+ , parSequence
68 -- ** Combine two
68 -- ** Combine two
69 -- | Use a channel for each pair.
69 -- | Use a channel for each pair.
@@ -78,28 +78,29 @@ module Streamly.Internal.Data.Stream.Concurrent
79 -- ** List of streams
79 -- ** List of streams
80 -- | Shares a single channel across many streams.
80 -- | Shares a single channel across many streams.
81− , append
81+ , parLazy
82− , interleave
82+ , parLazyOrdered
83− , ahead
83+ , parLazyInterleaved
84− , parallel
84+ , parEager
85− , parallelFst
85+ , parEagerFst
86− , parallelMin
86+ , parEagerMin
87− , concatListWith
87+ , parConcatList
89− , zipWith
89+ , parZipWithM
91 -- ** Stream of streams
92 -- ** Stream of streams
92 -- *** Apply
93 -- *** Apply
94− , applyWith
95+ , parApply
96 -- *** Concat
97 -- *** Concat
97 -- | Shares a single channel across many streams.
98 -- | Shares a single channel across many streams.
99− , concatWith
100+ , parConcat
100 , concatMap
101 , concatMap
101 , concatMapInterleave
102 , concatMapInterleave
102− , concatMapWith
103+ , parConcatMap
104 -- ** Reactive
105 -- ** Reactive
105 , fromCallback
106 , fromCallback
@@ -144,7 +145,7 @@ import Streamly.Internal.Data.Stream.Concurrent.Channel
144-- >>> import qualified Streamly.Data.Fold as Fold
145-- >>> import qualified Streamly.Data.Fold as Fold
145-- >>> import qualified Streamly.Data.Parser as Parser
146-- >>> import qualified Streamly.Data.Parser as Parser
146-- >>> import qualified Streamly.Data.Stream as Stream
147-- >>> import qualified Streamly.Data.Stream as Stream
147−-- >>> import qualified Streamly.Internal.Data.Stream.Concurrent as Concur
148+-- >>> import qualified Streamly.Internal.Data.Stream.Concurrent as Stream
148-- >>> import Prelude hiding (concatMap, concat, zipWith)
149-- >>> import Prelude hiding (concatMap, concat, zipWith)
150-- delay n = do
151-- delay n = do
@@ -158,9 +159,9 @@ import Streamly.Internal.Data.Stream.Concurrent.Channel
158-------------------------------------------------------------------------------
159-------------------------------------------------------------------------------
161−{-# INLINE_NORMAL evalWithD #-}
162+{-# INLINE_NORMAL parEvalD #-}
162−evalWithD :: MonadAsync m => (Config -> Config) -> D.Stream m a -> D.Stream m a
163+parEvalD :: MonadAsync m => (Config -> Config) -> D.Stream m a -> D.Stream m a
163−evalWithD modifier m = D.Stream step Nothing
164+parEvalD modifier m = D.Stream step Nothing
166 step _ Nothing = do
167 step _ Nothing = do
@@ -180,18 +181,23 @@ evalWithD modifier m = D.Stream step Nothing
180-- | Evaluate a stream asynchronously using a channel and serve the consumer
181-- | Evaluate a stream asynchronously using a channel and serve the consumer
181-- from the evaluation buffer.
182-- from the evaluation buffer.
184+-- Note that the evaluation requires a single thread as only one stream needs
185+-- to be evaluated. Therefore, the concurrency options that are relevant to
186+-- multiple streams won't apply here e.g. maxThreads, eager, interleaved,
187+-- ordered, stopWhen options won't have any effect.
183−{-# INLINE evalWith #-}
189+{-# INLINE parEval #-}
184−evalWith :: MonadAsync m => (Config -> Config) -> Stream m a -> Stream m a
190+parEval :: MonadAsync m => (Config -> Config) -> Stream m a -> Stream m a
185−evalWith modifier input = withChannel modifier input (const id)
191+parEval modifier input = withChannel modifier input (const id)
186− -- Stream.fromStreamD $ evalWithD cfg $ Stream.toStreamD stream
192+ -- Stream.fromStreamD $ parEvalD cfg $ Stream.toStreamD stream
188-- | Definition:
194-- | Definition:
190−-- >>> eval = Concur.evalWith id
196+-- >>> eval = Stream.parEval id
192{-# INLINE eval #-}
198{-# INLINE eval #-}
193eval :: MonadAsync m => Stream m a -> Stream m a
199eval :: MonadAsync m => Stream m a -> Stream m a
194−eval = evalWith id
200+eval = parEval id
196-------------------------------------------------------------------------------
202-------------------------------------------------------------------------------
197-- combining two streams
203-- combining two streams
@@ -232,18 +238,18 @@ appendWithK :: MonadAsync m =>
232appendWithK modifier stream1 stream2 =
238appendWithK modifier stream1 stream2 =
234 if getOrdered (modifier defaultConfig)
240 if getOrdered (modifier defaultConfig)
235− then concatMapWithK modifier id (stream1 `K.cons` K.fromPure stream2)
241+ then parConcatMapK modifier id (stream1 `K.cons` K.fromPure stream2)
236 else _appendGeneric Append.newChannel modifier stream1 stream2
242 else _appendGeneric Append.newChannel modifier stream1 stream2
238− concatMapWithK modifier id (stream1 `K.cons` K.fromPure stream2)
244+ parConcatMapK modifier id (stream1 `K.cons` K.fromPure stream2)
240-- | Evaluate the first stream in the current thread and add the second stream
246-- | Evaluate the first stream in the current thread and add the second stream
241-- to the supplied channel. This is to be used by a worker thread.
247-- to the supplied channel. This is to be used by a worker thread.
243−-- This can be used with concatMapWith:
249+-- This can be used with parConcatMap:
246−-- concatMap = K.concatMapWith (_appendWithChanK chan) f stream
252+-- concatMap = K.parConcatMap (_appendWithChanK chan) f stream
249{-# INLINE _appendWithChanK #-}
255{-# INLINE _appendWithChanK #-}
@@ -272,13 +278,13 @@ combineWith modifier stream1 stream2 =
272-- all streams. However, with this operation you can precisely control the
278-- all streams. However, with this operation you can precisely control the
273-- scheduling by creating arbitrary shape expression trees.
279-- scheduling by creating arbitrary shape expression trees.
275−-- >>> append2 = Concur.combineWith id
281+-- >>> append2 = Stream.combineWith id
277-- The following code finishes in 4 seconds:
283-- The following code finishes in 4 seconds:
279-- >>> stream1 = Stream.fromEffect (delay 4)
285-- >>> stream1 = Stream.fromEffect (delay 4)
280-- >>> stream2 = Stream.fromEffect (delay 2)
286-- >>> stream2 = Stream.fromEffect (delay 2)
281−-- >>> Stream.fold Fold.toList $ stream1 `Concur.append2` stream2
287+-- >>> Stream.fold Fold.toList $ stream1 `Stream.append2` stream2
@@ -291,7 +297,7 @@ append2 = combineWith id
291-- the left stream. This schedules all streams in a round robin fashion over
297-- the left stream. This schedules all streams in a round robin fashion over
292-- limited number of threads.
298-- limited number of threads.
294−-- >>> interleave2 = Concur.combineWith (Concur.interleaved True)
300+-- >>> interleave2 = Stream.combineWith (Stream.interleaved True)
296{-# INLINE interleave2 #-}
302{-# INLINE interleave2 #-}
297interleave2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
303interleave2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
@@ -299,7 +305,7 @@ interleave2 = combineWith (interleaved True)
300-- | Like 'append' but with 'ordered' on.
306-- | Like 'append' but with 'ordered' on.
302−-- >>> ahead2 = Concur.combineWith (Concur.ordered True)
308+-- >>> ahead2 = Stream.combineWith (Stream.ordered True)
304{-# INLINE ahead2 #-}
310{-# INLINE ahead2 #-}
305ahead2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
311ahead2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
@@ -307,7 +313,7 @@ ahead2 = combineWith (ordered True)
308-- | Like 'append2' but with 'eager' on.
314-- | Like 'append2' but with 'eager' on.
310−-- >>> parallel2 = Concur.combineWith (Concur.eager True)
316+-- >>> parallel2 = Stream.combineWith (Stream.eager True)
312{-# INLINE parallel2 #-}
318{-# INLINE parallel2 #-}
313parallel2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
319parallel2 :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
@@ -315,7 +321,7 @@ parallel2 = combineWith (eager True)
316-- | Like 'parallel2' but stops the output as soon as the first stream stops.
322-- | Like 'parallel2' but stops the output as soon as the first stream stops.
318−-- >>> parallelFst2 = Concur.combineWith (Concur.eager True . Concur.stopWhen Concur.FirstStops)
324+-- >>> parallelFst2 = Stream.combineWith (Stream.eager True . Stream.stopWhen Stream.FirstStops)
320-- /Pre-release/
326-- /Pre-release/
321{-# INLINE parallelFst2 #-}
327{-# INLINE parallelFst2 #-}
@@ -325,7 +331,7 @@ parallelFst2 = combineWith (eager True . stopWhen FirstStops)
325-- | Like 'parallel2' but stops the output as soon as any of the two streams
331-- | Like 'parallel2' but stops the output as soon as any of the two streams
328−-- >>> parallelMin2 = Concur.combineWith (Concur.eager True . Concur.stopWhen Concur.AnyStops)
334+-- >>> parallelMin2 = Stream.combineWith (Stream.eager True . Stream.stopWhen Stream.AnyStops)
330-- /Pre-release/
336-- /Pre-release/
331{-# INLINE parallelMin2 #-}
337{-# INLINE parallelMin2 #-}
@@ -366,26 +372,26 @@ mkEnqueue chan runner = do
367-- This function is designed to be used by worker threads on a channel to
373-- This function is designed to be used by worker threads on a channel to
368-- concurrently map and evaluate a stream.
374-- concurrently map and evaluate a stream.
369−{-# INLINE concatMapWithChanK #-}
375+{-# INLINE parConcatMapChanK #-}
370−concatMapWithChanK :: MonadAsync m =>
376+parConcatMapChanK :: MonadAsync m =>
371 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
377 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
372−concatMapWithChanK chan f stream =
378+parConcatMapChanK chan f stream =
373 let run q = concatMapDivK q f
379 let run q = concatMapDivK q f
374 in K.concatMapEffect (`run` stream) (mkEnqueue chan run)
380 in K.concatMapEffect (`run` stream) (mkEnqueue chan run)
375− -- K.concatMapWith (_appendWithChanK chan) f stream
381+ -- K.parConcatMap (_appendWithChanK chan) f stream
377−{-# INLINE concatMapWithChanKAny #-}
383+{-# INLINE parConcatMapChanKAny #-}
378−concatMapWithChanKAny :: MonadAsync m =>
384+parConcatMapChanKAny :: MonadAsync m =>
379 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
385 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
380−concatMapWithChanKAny chan f stream =
386+parConcatMapChanKAny chan f stream =
381 let done = K.nilM (stopChannel chan)
387 let done = K.nilM (stopChannel chan)
382 run q = concatMapDivK q (\x -> K.serial (f x) done)
388 run q = concatMapDivK q (\x -> K.serial (f x) done)
383 in K.concatMapEffect (`run` stream) (mkEnqueue chan run)
389 in K.concatMapEffect (`run` stream) (mkEnqueue chan run)
385−{-# INLINE concatMapWithChanKFirst #-}
391+{-# INLINE parConcatMapChanKFirst #-}
386−concatMapWithChanKFirst :: MonadAsync m =>
392+parConcatMapChanKFirst :: MonadAsync m =>
387 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
393 Channel m b -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
388−concatMapWithChanKFirst chan f stream =
394+parConcatMapChanKFirst chan f stream =
389 let done = K.nilM (stopChannel chan)
395 let done = K.nilM (stopChannel chan)
390 run q = concatMapDivK q f
396 run q = concatMapDivK q f
391 in K.concatEffect $ do
397 in K.concatEffect $ do
@@ -397,19 +403,19 @@ concatMapWithChanKFirst chan f stream =
398 return $ K.serial (f h) done
404 return $ K.serial (f h) done
400−{-# INLINE concatMapWithChanKGeneric #-}
406+{-# INLINE parConcatMapChanKGeneric #-}
401−concatMapWithChanKGeneric :: MonadAsync m =>
407+parConcatMapChanKGeneric :: MonadAsync m =>
402 (Config -> Config)
408 (Config -> Config)
403 -> Channel m b
409 -> Channel m b
404 -> (a -> K.Stream m b)
410 -> (a -> K.Stream m b)
405 -> K.Stream m a
411 -> K.Stream m a
406 -> K.Stream m b
412 -> K.Stream m b
407−concatMapWithChanKGeneric modifier chan f stream = do
413+parConcatMapChanKGeneric modifier chan f stream = do
408 let cfg = modifier defaultConfig
414 let cfg = modifier defaultConfig
409 case getStopWhen cfg of
415 case getStopWhen cfg of
410− AllStop -> concatMapWithChanK chan f stream
416+ AllStop -> parConcatMapChanK chan f stream
411− FirstStops -> concatMapWithChanKFirst chan f stream
417+ FirstStops -> parConcatMapChanKFirst chan f stream
412− AnyStops -> concatMapWithChanKAny chan f stream
418+ AnyStops -> parConcatMapChanKAny chan f stream
414-- XXX Add a deep evaluation variant that evaluates individual elements in the
420-- XXX Add a deep evaluation variant that evaluates individual elements in the
415-- generated streams in parallel.
421-- generated streams in parallel.
@@ -417,11 +423,11 @@ concatMapWithChanKGeneric modifier chan f stream = do
417-- | Allocate a channel and use it to concurrently evaluate the streams
423-- | Allocate a channel and use it to concurrently evaluate the streams
418-- generated by the mapped function.
424-- generated by the mapped function.
420−{-# INLINE concatMapWithK #-}
426+{-# INLINE parConcatMapK #-}
421−concatMapWithK :: MonadAsync m =>
427+parConcatMapK :: MonadAsync m =>
422 (Config -> Config) -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
428 (Config -> Config) -> (a -> K.Stream m b) -> K.Stream m a -> K.Stream m b
423−concatMapWithK modifier f input =
429+parConcatMapK modifier f input =
424− let g = concatMapWithChanKGeneric modifier
430+ let g = parConcatMapChanKGeneric modifier
425 in withChannelK modifier input (`g` f)
431 in withChannelK modifier input (`g` f)
427-- | Map each element of the input to a stream and then concurrently evaluate
433-- | Map each element of the input to a stream and then concurrently evaluate
@@ -431,11 +437,11 @@ concatMapWithK modifier f input =
432-- Definition:
438-- Definition:
434−-- >>> concatMapWith modifier f stream = Concur.concatWith modifier $ fmap f stream
440+-- >>> parConcatMap modifier f stream = Stream.parConcat modifier $ fmap f stream
436-- Examples:
442-- Examples:
438−-- >>> f cfg xs = Stream.fold Fold.toList $ Concur.concatMapWith cfg id $ Stream.fromList xs
444+-- >>> f cfg xs = Stream.fold Fold.toList $ Stream.parConcatMap cfg id $ Stream.fromList xs
440-- The following streams finish in 4 seconds:
446-- The following streams finish in 4 seconds:
@@ -451,140 +457,140 @@ concatMapWithK modifier f input =
451-- Limiting threads to 2 schedules the third stream only after one of the first
457-- Limiting threads to 2 schedules the third stream only after one of the first
452-- two has finished, releasing a thread:
458-- two has finished, releasing a thread:
454−-- >>> f (Concur.maxThreads 2) [stream1, stream2, stream3]
460+-- >>> f (Stream.maxThreads 2) [stream1, stream2, stream3]
456-- [2,1,4]
462-- [2,1,4]
458-- When used with a Single thread it behaves like serial concatMap:
464-- When used with a Single thread it behaves like serial concatMap:
460−-- >>> f (Concur.maxThreads 1) [stream1, stream2, stream3]
466+-- >>> f (Stream.maxThreads 1) [stream1, stream2, stream3]
462-- [4,2,1]
468-- [4,2,1]
464-- >>> stream1 = Stream.fromList [1,2,3]
470-- >>> stream1 = Stream.fromList [1,2,3]
465-- >>> stream2 = Stream.fromList [4,5,6]
471-- >>> stream2 = Stream.fromList [4,5,6]
466−-- >>> f (Concur.maxThreads 1) [stream1, stream2]
472+-- >>> f (Stream.maxThreads 1) [stream1, stream2]
467-- [1,2,3,4,5,6]
473-- [1,2,3,4,5,6]
469−{-# INLINE concatMapWith #-}
475+{-# INLINE parConcatMap #-}
470−concatMapWith :: MonadAsync m =>
476+parConcatMap :: MonadAsync m =>
471 (Config -> Config) -> (a -> Stream m b) -> Stream m a -> Stream m b
477 (Config -> Config) -> (a -> Stream m b) -> Stream m a -> Stream m b
472−concatMapWith modifier f stream =
478+parConcatMap modifier f stream =
473 Stream.fromStreamK
479 Stream.fromStreamK
474− $ concatMapWithK
480+ $ parConcatMapK
475 modifier (Stream.toStreamK . f) (Stream.toStreamK stream)
481 modifier (Stream.toStreamK . f) (Stream.toStreamK stream)
477-- | Definition:
483-- | Definition:
479−-- >>> concatMap = Concur.concatMapWith id
485+-- >>> concatMap = Stream.parConcatMap id
481{-# INLINE concatMap #-}
487{-# INLINE concatMap #-}
482concatMap :: MonadAsync m => (a -> Stream m b) -> Stream m a -> Stream m b
488concatMap :: MonadAsync m => (a -> Stream m b) -> Stream m a -> Stream m b
483−concatMap = concatMapWith id
489+concatMap = parConcatMap id
485-- | Map each element of the input to a stream and then concurrently evaluate
491-- | Map each element of the input to a stream and then concurrently evaluate
486-- and interleave the resulting streams. Unlike 'concatMap' which prefers to
492-- and interleave the resulting streams. Unlike 'concatMap' which prefers to
487-- evaluate the earlier stream first, this schedules all streams in a round
493-- evaluate the earlier stream first, this schedules all streams in a round
488-- robin fashion over the available threads.
494-- robin fashion over the available threads.
490−-- >>> concatMapInterleave = Concur.concatMapWith (Concur.interleaved True)
496+-- >>> concatMapInterleave = Stream.parConcatMap (Stream.interleaved True)
492-- When used with a single thread it behaves like serial interleaving:
498-- When used with a single thread it behaves like serial interleaving:
494−-- >>> f cfg xs = Stream.fold Fold.toList $ Concur.concatMapWith (Concur.interleaved True . cfg) id $ Stream.fromList xs
500+-- >>> f cfg xs = Stream.fold Fold.toList $ Stream.parConcatMap (Stream.interleaved True . cfg) id $ Stream.fromList xs
496-- >>> stream1 = Stream.fromList [1,2,3]
502-- >>> stream1 = Stream.fromList [1,2,3]
497-- >>> stream2 = Stream.fromList [4,5,6]
503-- >>> stream2 = Stream.fromList [4,5,6]
498−-- >>> f (Concur.maxThreads 1) [stream1, stream2]
504+-- >>> f (Stream.maxThreads 1) [stream1, stream2]
499-- [1,4,2,5,3,6]
505-- [1,4,2,5,3,6]
501-- /Works only on finite number of streams/
507-- /Works only on finite number of streams/
503{-# INLINE concatMapInterleave #-}
509{-# INLINE concatMapInterleave #-}
504concatMapInterleave :: MonadAsync m => (a -> Stream m b) -> Stream m a -> Stream m b
510concatMapInterleave :: MonadAsync m => (a -> Stream m b) -> Stream m a -> Stream m b
505−concatMapInterleave = concatMapWith (interleaved True)
511+concatMapInterleave = parConcatMap (interleaved True)
507-- | Evaluate the streams in the input stream concurrently and combine them.
513-- | Evaluate the streams in the input stream concurrently and combine them.
509−-- >>> concatWith modifier = Concur.concatMapWith modifier id
515+-- >>> parConcat modifier = Stream.parConcatMap modifier id
511−{-# INLINE concatWith #-}
517+{-# INLINE parConcat #-}
512−concatWith :: MonadAsync m =>
518+parConcat :: MonadAsync m =>
513 (Config -> Config) -> Stream m (Stream m a) -> Stream m a
519 (Config -> Config) -> Stream m (Stream m a) -> Stream m a
514−concatWith modifier = concatMapWith modifier id
520+parConcat modifier = parConcatMap modifier id
516-- | Definition:
522-- | Definition:
518−-- >>> concat = Concur.concatWith id
524+-- >>> concat = Stream.parConcat id
520{-# INLINE concat #-}
526{-# INLINE concat #-}
521concat :: MonadAsync m => Stream m (Stream m a) -> Stream m a
527concat :: MonadAsync m => Stream m (Stream m a) -> Stream m a
522−concat = concatWith id
528+concat = parConcat id
524-------------------------------------------------------------------------------
530-------------------------------------------------------------------------------
525-- concat Lists
531-- concat Lists
526-------------------------------------------------------------------------------
532-------------------------------------------------------------------------------
528−-- | Like 'concatWith' but works on a list of streams.
534+-- | Like 'parConcat' but works on a list of streams.
530−-- >>> concatListWith modifier = Concur.concatWith modifier . Stream.fromList
536+-- >>> parConcatList modifier = Stream.parConcat modifier . Stream.fromList
532−{-# INLINE concatListWith #-}
538+{-# INLINE parConcatList #-}
533−concatListWith :: MonadAsync m => (Config -> Config) -> [Stream m a] -> Stream m a
539+parConcatList :: MonadAsync m => (Config -> Config) -> [Stream m a] -> Stream m a
534−concatListWith modifier = concatWith modifier . Stream.fromList
540+parConcatList modifier = parConcat modifier . Stream.fromList
536-- | Like 'concat' but works on a list of streams.
542-- | Like 'concat' but works on a list of streams.
538−-- >>> append = Concur.concatListWith id
544+-- >>> parLazy = Stream.parConcatList id
540−{-# INLINE append #-}
546+{-# INLINE parLazy #-}
541−append :: MonadAsync m => [Stream m a] -> Stream m a
547+parLazy :: MonadAsync m => [Stream m a] -> Stream m a
542−append = concatListWith id
548+parLazy = parConcatList id
544−-- | Like 'append' but interleaves the streams fairly instead of prioritizing
550+-- | Like 'parLazy' but interleaves the streams fairly instead of prioritizing
545-- the left stream. This schedules all streams in a round robin fashion over
551-- the left stream. This schedules all streams in a round robin fashion over
546-- limited number of threads.
552-- limited number of threads.
548−-- >>> interleave = Concur.concatListWith (Concur.interleaved True)
554+-- >>> parLazyInterleaved = Stream.parConcatList (Stream.interleaved True)
550−{-# INLINE interleave #-}
556+{-# INLINE parLazyInterleaved #-}
551−interleave :: MonadAsync m => [Stream m a] -> Stream m a
557+parLazyInterleaved :: MonadAsync m => [Stream m a] -> Stream m a
552−interleave = concatListWith (interleaved True)
558+parLazyInterleaved = parConcatList (interleaved True)
554−-- | Like 'append' but with 'ordered' on.
560+-- | Like 'parLazy' but with 'ordered' on.
556−-- >>> ahead = Concur.concatListWith (Concur.ordered True)
562+-- >>> parLazyOrdered = Stream.parConcatList (Stream.ordered True)
558−{-# INLINE ahead #-}
564+{-# INLINE parLazyOrdered #-}
559−ahead :: MonadAsync m => [Stream m a] -> Stream m a
565+parLazyOrdered :: MonadAsync m => [Stream m a] -> Stream m a
560−ahead = concatListWith (ordered True)
566+parLazyOrdered = parConcatList (ordered True)
562−-- | Like 'append' but with 'eager' on.
568+-- | Like 'parLazy' but with 'eager' on.
564−-- >>> parallel = Concur.concatListWith (Concur.eager True)
570+-- >>> parEager = Stream.parConcatList (Stream.eager True)
566−{-# INLINE parallel #-}
572+{-# INLINE parEager #-}
567−parallel :: MonadAsync m => [Stream m a] -> Stream m a
573+parEager :: MonadAsync m => [Stream m a] -> Stream m a
568−parallel = concatListWith (eager True)
574+parEager = parConcatList (eager True)
570−-- | Like 'parallel' but stops the output as soon as the first stream stops.
576+-- | Like 'parEager' but stops the output as soon as the first stream stops.
572−-- >>> parallelFst = Concur.concatListWith (Concur.eager True . Concur.stopWhen Concur.FirstStops)
578+-- >>> parEagerFst = Stream.parConcatList (Stream.eager True . Stream.stopWhen Stream.FirstStops)
574−{-# INLINE parallelFst #-}
580+{-# INLINE parEagerFst #-}
575−parallelFst :: MonadAsync m => [Stream m a] -> Stream m a
581+parEagerFst :: MonadAsync m => [Stream m a] -> Stream m a
576−parallelFst = concatListWith (eager True . stopWhen FirstStops)
582+parEagerFst = parConcatList (eager True . stopWhen FirstStops)
578−-- | Like 'parallel' but stops the output as soon as any of the two streams
584+-- | Like 'parEager' but stops the output as soon as any of the two streams
581-- Definition:
587-- Definition:
583−-- >>> parallelMin = Concur.concatListWith (Concur.eager True . Concur.stopWhen Concur.AnyStops)
589+-- >>> parEagerMin = Stream.parConcatList (Stream.eager True . Stream.stopWhen Stream.AnyStops)
585−{-# INLINE parallelMin #-}
591+{-# INLINE parEagerMin #-}
586−parallelMin :: MonadAsync m => [Stream m a] -> Stream m a
592+parEagerMin :: MonadAsync m => [Stream m a] -> Stream m a
587−parallelMin = concatListWith (eager True . stopWhen AnyStops)
593+parEagerMin = parConcatList (eager True . stopWhen AnyStops)
589-------------------------------------------------------------------------------
595-------------------------------------------------------------------------------
590-- Applicative
596-- Applicative
@@ -592,21 +598,21 @@ parallelMin = concatListWith (eager True . stopWhen AnyStops)
593-- | Apply an argument stream to a function stream concurrently. Uses a
599-- | Apply an argument stream to a function stream concurrently. Uses a
594-- shared channel for all individual applications within a stream application.
600-- shared channel for all individual applications within a stream application.
595−{-# INLINE applyWith #-}
601+{-# INLINE parApply #-}
596−{-# SPECIALIZE applyWith ::
602+{-# SPECIALIZE parApply ::
597 (Config -> Config) -> Stream IO (a -> b) -> Stream IO a -> Stream IO b #-}
603 (Config -> Config) -> Stream IO (a -> b) -> Stream IO a -> Stream IO b #-}
598−applyWith :: MonadAsync m =>
604+parApply :: MonadAsync m =>
599 (Config -> Config) -> Stream m (a -> b) -> Stream m a -> Stream m b
605 (Config -> Config) -> Stream m (a -> b) -> Stream m a -> Stream m b
600−applyWith modifier stream1 stream2 =
606+parApply modifier stream1 stream2 =
601− concatMapWith
607+ parConcatMap
603− (\g -> concatMapWith modifier (pure . g) stream2)
609+ (\g -> parConcatMap modifier (pure . g) stream2)
606{-# INLINE apply #-}
612{-# INLINE apply #-}
607{-# SPECIALIZE apply :: Stream IO (a -> b) -> Stream IO a -> Stream IO b #-}
613{-# SPECIALIZE apply :: Stream IO (a -> b) -> Stream IO a -> Stream IO b #-}
608apply :: MonadAsync m => Stream m (a -> b) -> Stream m a -> Stream m b
614apply :: MonadAsync m => Stream m (a -> b) -> Stream m a -> Stream m b
609−apply = applyWith id
615+apply = parApply id
611-------------------------------------------------------------------------------
617-------------------------------------------------------------------------------
@@ -615,79 +621,85 @@ apply = applyWith id
616-- Definition:
622-- Definition:
618−-- >>> mapMWith modifier f = Concur.concatMapWith modifier (Stream.fromEffect . f)
624+-- >>> parMapM modifier f = Stream.parConcatMap modifier (Stream.fromEffect . f)
620-- Example, the following example finishes in 1 second as all actions run in
626-- Example, the following example finishes in 1 second as all actions run in
621-- parallel. Even though results are available out of order they are ordered
627-- parallel. Even though results are available out of order they are ordered
622-- due to the config option::
628-- due to the config option::
624-- >>> f x = delay x >> return x
630-- >>> f x = delay x >> return x
625−-- >>> Stream.fold Fold.toList $ Concur.mapMWith (Concur.ordered True) f $ Stream.fromList [3,2,1]
631+-- >>> Stream.fold Fold.toList $ Stream.parMapM (Stream.ordered True) f $ Stream.fromList [3,2,1]
629-- [3,2,1]
635-- [3,2,1]
631−{-# INLINE mapMWith #-}
637+{-# INLINE parMapM #-}
632−mapMWith :: MonadAsync m =>
638+parMapM :: MonadAsync m =>
633 (Config -> Config) -> (a -> m b) -> Stream m a -> Stream m b
639 (Config -> Config) -> (a -> m b) -> Stream m a -> Stream m b
634−mapMWith modifier f = concatMapWith modifier (Stream.fromEffect . f)
640+parMapM modifier f = parConcatMap modifier (Stream.fromEffect . f)
637-- Definition:
643-- Definition:
639−-- >>> mapM = Concur.mapMWith id
645+-- >>> mapM = Stream.parMapM id
641−-- Example, the following example finishes in 1 second as all actions run in
642−-- parallel, by default, the results are output as soon as they are available::
644−-- >>> f x = delay x >> return x
645−-- >>> Stream.fold Fold.toList $ Concur.mapM f $ Stream.fromList [3,2,1]
651{-# INLINE mapM #-}
647{-# INLINE mapM #-}
652mapM :: MonadAsync m => (a -> m b) -> Stream m a -> Stream m b
648mapM :: MonadAsync m => (a -> m b) -> Stream m a -> Stream m b
653−mapM = mapMWith id
649+mapM = parMapM id
656−-- >>> sequenceWith modifier = Concur.mapMWith modifier id
652+-- >>> parSequence modifier = Stream.parMapM modifier id
658−{-# INLINE sequenceWith #-}
654+{-# INLINE parSequence #-}
659−sequenceWith :: MonadAsync m =>
655+parSequence :: MonadAsync m =>
660 (Config -> Config) -> Stream m (m a) -> Stream m a
656 (Config -> Config) -> Stream m (m a) -> Stream m a
661−sequenceWith modifier = mapMWith modifier id
657+parSequence modifier = parMapM modifier id
664−-- >>> sequence = Concur.sequenceWith id
660+-- >>> sequence = Stream.parSequence id
666{-# INLINE sequence #-}
662{-# INLINE sequence #-}
667sequence :: MonadAsync m =>
663sequence :: MonadAsync m =>
668 Stream m (m a) -> Stream m a
664 Stream m (m a) -> Stream m a
669−sequence = sequenceWith id
665+sequence = parSequence id
671−-- |
667+-- | Evaluates the streams being zipped in separate threads than the consumer.
672−-- >>> zipWithM f m1 m2 = Stream.zipWithM f (Concur.eval m1) (Concur.eval m2)
668+-- The zip function is evaluated in the consumer thread.
670+-- >>> parZipWithM cfg f m1 m2 = Stream.zipWithM f (Stream.parEval cfg m1) (Stream.parEval cfg m2)
674−{-# INLINE zipWithM #-}
672+-- Multi-stream concurrency options won't apply here, see the notes in
675+-- If you want to evaluate the zip function as well in a separate thread, you
676+-- can use a 'parEval' on 'parZipWithM'.
678+{-# INLINE parZipWithM #-}
675−zipWithM :: MonadAsync m
679+parZipWithM :: MonadAsync m
680+ => (Config -> Config)
676− => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
682+ -> Stream m a
677−zipWithM f m1 m2 = Stream.zipWithM f (eval m1) (eval m2)
685+parZipWithM cfg f m1 m2 = Stream.zipWithM f (parEval cfg m1) (parEval cfg m2)
680−-- >>> zipWith f = Stream.zipWithM (\a b -> return $ f a b)
688+-- >>> parZipWith cfg f = Stream.parZipWithM cfg (\a b -> return $ f a b)
682-- >>> m1 = Stream.fromList [1,2,3]
690-- >>> m1 = Stream.fromList [1,2,3]
683-- >>> m2 = Stream.fromList [4,5,6]
691-- >>> m2 = Stream.fromList [4,5,6]
684−-- >>> Stream.fold Fold.toList $ Concur.zipWith (,) m1 m2
692+-- >>> Stream.fold Fold.toList $ Stream.parZipWith id (,) m1 m2
685-- [(1,4),(2,5),(3,6)]
693-- [(1,4),(2,5),(3,6)]
687−{-# INLINE zipWith #-}
695+{-# INLINE parZipWith #-}
688−zipWith :: MonadAsync m
696+parZipWith :: MonadAsync m
697+ => (Config -> Config)
689− => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
699+ -> Stream m a
690−zipWith f = zipWithM (\a b -> return $ f a b)
700+ -> Stream m b
702+parZipWith cfg f = parZipWithM cfg (\a b -> return $ f a b)
692-------------------------------------------------------------------------------
704-------------------------------------------------------------------------------
693-- Generate
705-- Generate
@@ -696,46 +708,46 @@ zipWith f = zipWithM (\a b -> return $ f a b)
697-- Definition:
709-- Definition:
699−-- >>> repeatMWith cfg = Concur.sequenceWith cfg . Stream.repeat
711+-- >>> parRepeatM cfg = Stream.parSequence cfg . Stream.repeat
701-- Generate a stream by repeatedly executing a monadic action forever.
713-- Generate a stream by repeatedly executing a monadic action forever.
702−{-# INLINE repeatMWith #-}
714+{-# INLINE parRepeatM #-}
703−repeatMWith :: MonadAsync m => (Config -> Config) -> m a -> Stream m a
715+parRepeatM :: MonadAsync m => (Config -> Config) -> m a -> Stream m a
704−repeatMWith cfg = sequenceWith cfg . Stream.repeat
716+parRepeatM cfg = parSequence cfg . Stream.repeat
707-- Definition:
719-- Definition:
709−-- >>> repeatM = Concur.repeatMWith id
721+-- >>> repeatM = Stream.parRepeatM id
711{-# INLINE repeatM #-}
723{-# INLINE repeatM #-}
712repeatM :: MonadAsync m => m a -> Stream m a
724repeatM :: MonadAsync m => m a -> Stream m a
713−repeatM = repeatMWith id
725+repeatM = parRepeatM id
715-- | Generate a stream by concurrently performing a monadic action @n@ times.
727-- | Generate a stream by concurrently performing a monadic action @n@ times.
717-- Definition:
729-- Definition:
719−-- >>> replicateMWith cfg n = Concur.sequenceWith cfg . Stream.replicate n
731+-- >>> parReplicateM cfg n = Stream.parSequence cfg . Stream.replicate n
721−-- Example, 'replicateMWith' in the following example executes all the
733+-- Example, 'parReplicateM' in the following example executes all the
722-- replicated actions concurrently, thus taking only 1 second:
734-- replicated actions concurrently, thus taking only 1 second:
724−-- >>> Stream.fold Fold.drain $ Concur.replicateMWith id 10 $ delay 1
736+-- >>> Stream.fold Fold.drain $ Stream.parReplicateM id 10 $ delay 1
727−{-# INLINE replicateMWith #-}
739+{-# INLINE parReplicateM #-}
728−replicateMWith :: MonadAsync m => (Config -> Config) -> Int -> m a -> Stream m a
740+parReplicateM :: MonadAsync m => (Config -> Config) -> Int -> m a -> Stream m a
729−replicateMWith cfg n = sequenceWith cfg . Stream.replicate n
741+parReplicateM cfg n = parSequence cfg . Stream.replicate n
732-- Definition:
744-- Definition:
734−-- >>> replicateM n = Concur.replicateMWith id
746+-- >>> replicateM n = Stream.parReplicateM id
736{-# INLINE replicateM #-}
748{-# INLINE replicateM #-}
737replicateM :: MonadAsync m => Int -> m a -> Stream m a
749replicateM :: MonadAsync m => Int -> m a -> Stream m a
738−replicateM = replicateMWith id
750+replicateM = parReplicateM id
740-------------------------------------------------------------------------------
752-------------------------------------------------------------------------------
741-- Reactive
753-- Reactive
@@ -824,7 +836,7 @@ pollCountsD predicate fld (D.Stream step state) = D.Stream step' Nothing
824-- For example, to print the count of elements processed every second:
836-- For example, to print the count of elements processed every second:
827−-- > Stream.drain $ Concur.pollCounts (const True) (Stream.rollingMap (-) . Stream.delayPost 1) (Fold.drainBy print)
839+-- > Stream.drain $ Stream.pollCounts (const True) (Stream.rollingMap (-) . Stream.delayPost 1) (Fold.drainBy print)
828-- $ Stream.enumerateFrom 0
840-- $ Stream.enumerateFrom 0