on master help sign in
Rename concatUnfold to unfoldMany #986
b73b5ffRanjeet Kumar Ranjan
benchmark/Streamly/Benchmark/Data/Stream/StreamD.hs+11−11
@@ -402,20 +402,20 @@ inspect $ hasNoTypeClasses 'concatMapRepl
402inspect $ 'concatMapRepl `hasNoType` ''SPEC
402inspect $ 'concatMapRepl `hasNoType` ''SPEC
403#endif
403#endif
404
404
405−-- concatUnfold replicate/unfoldrM
405+-- unfoldMany replicate/unfoldrM
406
406
407−{-# INLINE concatUnfoldRepl #-}
407+{-# INLINE unfoldManyRepl #-}
408−concatUnfoldRepl :: Int -> Int -> Int -> IO ()
408+unfoldManyRepl :: Int -> Int -> Int -> IO ()
409−concatUnfoldRepl outer inner n =
409+unfoldManyRepl outer inner n =
410 S.drain
410 S.drain
411− $ S.concatUnfold
411+ $ S.unfoldMany
412 (UF.lmap return (UF.replicateM inner))
412 (UF.lmap return (UF.replicateM inner))
413 (sourceUnfoldrMN outer n)
413 (sourceUnfoldrMN outer n)
414
414
415#ifdef INSPECTION
415#ifdef INSPECTION
416−inspect $ hasNoTypeClasses 'concatUnfoldRepl
416+inspect $ hasNoTypeClasses 'unfoldManyRepl
417−inspect $ 'concatUnfoldRepl `hasNoType` ''S.ConcatMapUState
417+inspect $ 'unfoldManyRepl `hasNoType` ''S.ConcatMapUState
418−inspect $ 'concatUnfoldRepl `hasNoType` ''SPEC
418+inspect $ 'unfoldManyRepl `hasNoType` ''SPEC
419#endif
419#endif
420
420
421-------------------------------------------------------------------------------
421-------------------------------------------------------------------------------
@@ -488,11 +488,11 @@ o_1_space =
488 , benchIOSrc1 "concatMap (1 of n)"
488 , benchIOSrc1 "concatMap (1 of n)"
489 (concatMap 1 value)
489 (concatMap 1 value)
490
490
491− -- concatMap vs concatUnfold
491+ -- concatMap vs unfoldMany
492 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
492 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
493 (concatMapRepl value2 value2)
493 (concatMapRepl value2 value2)
494− , benchIOSrc1 "concatUnfoldRepl (sqrt n of sqrt n)"
494+ , benchIOSrc1 "unfoldManyRepl (sqrt n of sqrt n)"
495− (concatUnfoldRepl value2 value2)
495+ (unfoldManyRepl value2 value2)
496 ]
496 ]
497 , bgroup "filtering"
497 , bgroup "filtering"
498 [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
498 [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
benchmark/Streamly/Benchmark/FileSystem/Handle/Read.hs+1−1
@@ -286,7 +286,7 @@ toChunksConcatUnfoldCountLines inh =
286 $ IUS.lines FL.drain
286 $ IUS.lines FL.drain
287 $ SS.decodeLatin1
287 $ SS.decodeLatin1
288 -- XXX replace with toBytes
288 -- XXX replace with toBytes
289− $ S.concatUnfold A.read (IFH.toChunks inh)
289+ $ S.unfoldMany A.read (IFH.toChunks inh)
290
290
291#ifdef INSPECTION
291#ifdef INSPECTION
292inspect $ hasNoTypeClasses 'toChunksConcatUnfoldCountLines
292inspect $ hasNoTypeClasses 'toChunksConcatUnfoldCountLines
benchmark/Streamly/Benchmark/Prelude/Serial/Nested.hs+12−12
@@ -261,22 +261,22 @@ inspect $ hasNoTypeClasses 'concatMapWithAppend
261inspect $ 'concatMapWithAppend `hasNoType` ''SPEC
261inspect $ 'concatMapWithAppend `hasNoType` ''SPEC
262#endif
262#endif
263
263
264−-- concatUnfold
264+-- unfoldMany
265
265
266−-- concatUnfold replicate/unfoldrM
266+-- unfoldMany replicate/unfoldrM
267
267
268−{-# INLINE concatUnfoldRepl #-}
268+{-# INLINE unfoldManyRepl #-}
269−concatUnfoldRepl :: Int -> Int -> Int -> IO ()
269+unfoldManyRepl :: Int -> Int -> Int -> IO ()
270−concatUnfoldRepl outer inner n =
270+unfoldManyRepl outer inner n =
271 S.drain
271 S.drain
272− $ S.concatUnfold
272+ $ S.unfoldMany
273 (UF.lmap return (UF.replicateM inner))
273 (UF.lmap return (UF.replicateM inner))
274 (sourceUnfoldrM outer n)
274 (sourceUnfoldrM outer n)
275
275
276#ifdef INSPECTION
276#ifdef INSPECTION
277−inspect $ hasNoTypeClasses 'concatUnfoldRepl
277+inspect $ hasNoTypeClasses 'unfoldManyRepl
278−inspect $ 'concatUnfoldRepl `hasNoType` ''D.ConcatMapUState
278+inspect $ 'unfoldManyRepl `hasNoType` ''D.ConcatMapUState
279−inspect $ 'concatUnfoldRepl `hasNoType` ''SPEC
279+inspect $ 'unfoldManyRepl `hasNoType` ''SPEC
280#endif
280#endif
281
281
282o_1_space_concat :: Int -> [Benchmark]
282o_1_space_concat :: Int -> [Benchmark]
@@ -322,11 +322,11 @@ o_1_space_concat value = sqrtVal `seq`
322 , benchIOSrc1 "concatMapWithAppend (2 of n/2)"
322 , benchIOSrc1 "concatMapWithAppend (2 of n/2)"
323 (concatMapWithAppend 2 (value `div` 2))
323 (concatMapWithAppend 2 (value `div` 2))
324
324
325− -- concatMap vs concatUnfold
325+ -- concatMap vs unfoldMany
326 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
326 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
327 (concatMapRepl sqrtVal sqrtVal)
327 (concatMapRepl sqrtVal sqrtVal)
328− , benchIOSrc1 "concatUnfoldRepl (sqrt n of sqrt n)"
328+ , benchIOSrc1 "unfoldManyRepl (sqrt n of sqrt n)"
329− (concatUnfoldRepl sqrtVal sqrtVal)
329+ (unfoldManyRepl sqrtVal sqrtVal)
330 ]
330 ]
331 ]
331 ]
332
332
benchmark/Streamly/Benchmark/Prelude/WSerial.hs+18−18
@@ -122,31 +122,31 @@ o_1_space_concat value =
122 ]
122 ]
123 ]
123 ]
124
124
125−{-# INLINE concatUnfoldInterleaveRepl4xN #-}
125+{-# INLINE unfoldManyInterleaveRepl4xN #-}
126−concatUnfoldInterleaveRepl4xN :: Int -> Int -> IO ()
126+unfoldManyInterleaveRepl4xN :: Int -> Int -> IO ()
127−concatUnfoldInterleaveRepl4xN value n =
127+unfoldManyInterleaveRepl4xN value n =
128− S.drain $ Internal.concatUnfoldInterleave
128+ S.drain $ Internal.unfoldManyInterleave
129 (UF.lmap return (UF.replicateM 4))
129 (UF.lmap return (UF.replicateM 4))
130 (sourceUnfoldrM (value `div` 4) n)
130 (sourceUnfoldrM (value `div` 4) n)
131
131
132#ifdef INSPECTION
132#ifdef INSPECTION
133−inspect $ hasNoTypeClasses 'concatUnfoldInterleaveRepl4xN
133+inspect $ hasNoTypeClasses 'unfoldManyInterleaveRepl4xN
134−-- inspect $ 'concatUnfoldInterleaveRepl4xN `hasNoType` ''SPEC
134+-- inspect $ 'unfoldManyInterleaveRepl4xN `hasNoType` ''SPEC
135−-- inspect $ 'concatUnfoldInterleaveRepl4xN `hasNoType`
135+-- inspect $ 'unfoldManyInterleaveRepl4xN `hasNoType`
136-- ''D.ConcatUnfoldInterleaveState
136-- ''D.ConcatUnfoldInterleaveState
137#endif
137#endif
138
138
139−{-# INLINE concatUnfoldRoundrobinRepl4xN #-}
139+{-# INLINE unfoldManyRoundRobinRepl4xN #-}
140−concatUnfoldRoundrobinRepl4xN :: Int -> Int -> IO ()
140+unfoldManyRoundRobinRepl4xN :: Int -> Int -> IO ()
141−concatUnfoldRoundrobinRepl4xN value n =
141+unfoldManyRoundRobinRepl4xN value n =
142− S.drain $ Internal.concatUnfoldRoundrobin
142+ S.drain $ Internal.unfoldManyRoundRobin
143 (UF.lmap return (UF.replicateM 4))
143 (UF.lmap return (UF.replicateM 4))
144 (sourceUnfoldrM (value `div` 4) n)
144 (sourceUnfoldrM (value `div` 4) n)
145
145
146#ifdef INSPECTION
146#ifdef INSPECTION
147−inspect $ hasNoTypeClasses 'concatUnfoldRoundrobinRepl4xN
147+inspect $ hasNoTypeClasses 'unfoldManyRoundRobinRepl4xN
148−-- inspect $ 'concatUnfoldRoundrobinRepl4xN `hasNoType` ''SPEC
148+-- inspect $ 'unfoldManyRoundRobinRepl4xN `hasNoType` ''SPEC
149−-- inspect $ 'concatUnfoldRoundrobinRepl4xN `hasNoType`
149+-- inspect $ 'unfoldManyRoundRobinRepl4xN `hasNoType`
150-- ''D.ConcatUnfoldInterleaveState
150-- ''D.ConcatUnfoldInterleaveState
151#endif
151#endif
152
152
@@ -159,11 +159,11 @@ o_n_heap_concat value =
159 -- WSerial expands slowly because of binary interleave behavior and
159 -- WSerial expands slowly because of binary interleave behavior and
160 -- this expands immediately because of Nary interleave behavior.
160 -- this expands immediately because of Nary interleave behavior.
161 benchIOSrc1
161 benchIOSrc1
162− "concatUnfoldInterleaveRepl (x/4,4)"
162+ "unfoldManyInterleaveRepl (x/4,4)"
163− (concatUnfoldInterleaveRepl4xN value)
163+ (unfoldManyInterleaveRepl4xN value)
164 , benchIOSrc1
164 , benchIOSrc1
165− "concatUnfoldRoundrobinRepl (x/4,4)"
165+ "unfoldManyRoundRobinRepl (x/4,4)"
166− (concatUnfoldRoundrobinRepl4xN value)
166+ (unfoldManyRoundRobinRepl4xN value)
167 ]
167 ]
168 ]
168 ]
169
169
design/optimization-guidelines.md+1−1
@@ -52,7 +52,7 @@ The haddock documentation includes a note when an operation cannot fuse.
52### Unfolds
52### Unfolds
53
53
54* Use unfolds especially when higher order operations are involved. For
54* Use unfolds especially when higher order operations are involved. For
55− example, `concatUnfold` can fuse completely whereas `concatMap` would
55+ example, `unfoldMany` can fuse completely whereas `concatMap` would
56 not fuse.
56 not fuse.
57* Use `outerProduct` in `Unfold` module instead of using the monad instance of
57* Use `outerProduct` in `Unfold` module instead of using the monad instance of
58 streams to fuse nested loops where performance matters. See the unfold
58 streams to fuse nested loops where performance matters. See the unfold
docs/Build.md+1−1
@@ -167,7 +167,7 @@ we can resolve this using fusion-plugin in future.
167### Delayed INLINE
167### Delayed INLINE
168
168
169When a function is passed to a higher order function e.g. a function
169When a function is passed to a higher order function e.g. a function
170−passed to `concatMap` or `concatUnfold` then we want the function to be
170+passed to `concatMap` or `unfoldMany` then we want the function to be
171inlined after the higher order is inlined so that proper fusion of the
171inlined after the higher order is inlined so that proper fusion of the
172higher order function can occur. For such cases we usually add INLINE[1]
172higher order function can occur. For such cases we usually add INLINE[1]
173on the function being passed to instruct GHC not to inline it too early.
173on the function being passed to instruct GHC not to inline it too early.
src/Streamly/Data/Unfold.hs+1−1
@@ -30,7 +30,7 @@
30-- much less efficient when compared to combinators using 'Unfold'. For
30-- much less efficient when compared to combinators using 'Unfold'. For
31-- example, the 'Streamly.Prelude.concatMap' combinator which uses @a -> t m b@
31-- example, the 'Streamly.Prelude.concatMap' combinator which uses @a -> t m b@
32-- (where @t@ is a stream type) to generate streams is much less efficient
32-- (where @t@ is a stream type) to generate streams is much less efficient
33−-- compared to 'Streamly.Prelude.concatUnfold'.
33+-- compared to 'Streamly.Prelude.unfoldMany'.
34--
34--
35-- On the other hand, transformation operations on stream types are as
35-- On the other hand, transformation operations on stream types are as
36-- efficient as transformations on 'Unfold'.
36-- efficient as transformations on 'Unfold'.
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+3−3
@@ -569,7 +569,7 @@ data FlattenState s a =
569
569
570-- | Use the "read" unfold instead.
570-- | Use the "read" unfold instead.
571--
571--
572−-- @flattenArrays = concatUnfold read@
572+-- @flattenArrays = unfoldMany read@
573--
573--
574-- We can try this if there are any fusion issues in the unfold.
574-- We can try this if there are any fusion issues in the unfold.
575--
575--
@@ -603,7 +603,7 @@ flattenArrays (D.Stream step state) = D.Stream step' (OuterLoop state)
603
603
604-- | Use the "readRev" unfold instead.
604-- | Use the "readRev" unfold instead.
605--
605--
606−-- @flattenArrays = concatUnfold readRev@
606+-- @flattenArrays = unfoldMany readRev@
607--
607--
608-- We can try this if there are any fusion issues in the unfold.
608-- We can try this if there are any fusion issues in the unfold.
609--
609--
@@ -987,7 +987,7 @@ fromStreamD :: (MonadIO m, Storable a) => D.Stream m a -> m (Array a)
987fromStreamD m = do
987fromStreamD m = do
988 buffered <- bufferChunks m
988 buffered <- bufferChunks m
989 len <- K.foldl' (+) 0 (K.map length buffered)
989 len <- K.foldl' (+) 0 (K.map length buffered)
990− fromStreamDN len $ D.concatUnfold read $ D.fromStreamK buffered
990+ fromStreamDN len $ D.unfoldMany read $ D.fromStreamK buffered
991
991
992-- | Create an 'Array' from a list. The list must be of finite size.
992-- | Create an 'Array' from a list. The list must be of finite size.
993--
993--
src/Streamly/Internal/Data/Array/Foreign/Type.hs+2−2
@@ -334,7 +334,7 @@ arraysOf n str = D.map unsafeFreeze $ MA.arraysOf n str
334
334
335-- | Use the "read" unfold instead.
335-- | Use the "read" unfold instead.
336--
336--
337−-- @flattenArrays = concatUnfold read@
337+-- @flattenArrays = unfoldMany read@
338--
338--
339-- We can try this if there are any fusion issues in the unfold.
339-- We can try this if there are any fusion issues in the unfold.
340--
340--
@@ -345,7 +345,7 @@ flattenArrays = MA.flattenArrays . D.map unsafeThaw
345
345
346-- | Use the "readRev" unfold instead.
346-- | Use the "readRev" unfold instead.
347--
347--
348−-- @flattenArrays = concatUnfold readRev@
348+-- @flattenArrays = unfoldMany readRev@
349--
349--
350-- We can try this if there are any fusion issues in the unfold.
350-- We can try this if there are any fusion issues in the unfold.
351--
351--
src/Streamly/Internal/Data/Array/PrimInclude.hs+1−1
@@ -173,7 +173,7 @@ last arr = readIndex arr (length arr - 1)
173concat :: (IsStream t, MonadIO m, Prim a) => t m (Array a) -> t m a
173concat :: (IsStream t, MonadIO m, Prim a) => t m (Array a) -> t m a
174-- concat m = D.fromStreamD $ A.flattenArrays (D.toStreamD m)
174-- concat m = D.fromStreamD $ A.flattenArrays (D.toStreamD m)
175-- concat m = D.fromStreamD $ D.concatMap A.toStreamD (D.toStreamD m)
175-- concat m = D.fromStreamD $ D.concatMap A.toStreamD (D.toStreamD m)
176−concat m = D.fromStreamD $ D.concatUnfold read (D.toStreamD m)
176+concat m = D.fromStreamD $ D.unfoldMany read (D.toStreamD m)
177
177
178-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
178-- | Coalesce adjacent arrays in incoming stream to form bigger arrays of a
179-- maximum specified size in bytes.
179-- maximum specified size in bytes.
src/Streamly/Internal/Data/Array/Stream/Foreign.hs+3−3
@@ -93,19 +93,19 @@ arraysOf n str = D.fromStreamD $ A.arraysOf n (D.toStreamD str)
93--
93--
94-- Same as the following but more efficient:
94-- Same as the following but more efficient:
95--
95--
96−-- > concat = Stream.concatUnfold Array.read
96+-- > concat = Stream.unfoldMany Array.read
97--
97--
98-- @since 0.7.0
98-- @since 0.7.0
99{-# INLINE concat #-}
99{-# INLINE concat #-}
100concat :: (IsStream t, MonadIO m, Storable a) => t m (Array a) -> t m a
100concat :: (IsStream t, MonadIO m, Storable a) => t m (Array a) -> t m a
101-- concat m = D.fromStreamD $ A.flattenArrays (D.toStreamD m)
101-- concat m = D.fromStreamD $ A.flattenArrays (D.toStreamD m)
102-- concat m = D.fromStreamD $ D.concatMap A.toStreamD (D.toStreamD m)
102-- concat m = D.fromStreamD $ D.concatMap A.toStreamD (D.toStreamD m)
103−concat m = D.fromStreamD $ D.concatUnfold A.read (D.toStreamD m)
103+concat m = D.fromStreamD $ D.unfoldMany A.read (D.toStreamD m)
104
104
105-- | Convert a stream of arrays into a stream of their elements reversing the
105-- | Convert a stream of arrays into a stream of their elements reversing the
106-- contents of each array before flattening.
106-- contents of each array before flattening.
107--
107--
108−-- > concatRev = Stream.concatUnfold Array.readRev
108+-- > concatRev = Stream.unfoldMany Array.readRev
109--
109--
110-- @since 0.7.0
110-- @since 0.7.0
111{-# INLINE concatRev #-}
111{-# INLINE concatRev #-}
src/Streamly/Internal/Data/Stream/IsStream/Common.hs+1−1
@@ -460,7 +460,7 @@ concatMapM f m = fromStreamD $ D.concatMapM (fmap toStreamD . f) (toStreamD m)
460-- concatMap f = 'concatMapM' (return . f)
460-- concatMap f = 'concatMapM' (return . f)
461-- concatMap = 'concatMapWith' 'Serial.serial'
461-- concatMap = 'concatMapWith' 'Serial.serial'
462-- concatMap f = 'concat . map f'
462-- concatMap f = 'concat . map f'
463−-- concatMap f = 'concatUnfold' (UF.lmap f UF.fromStream)
463+-- concatMap f = 'unfoldMany' (UF.lmap f UF.fromStream)
464-- @
464-- @
465--
465--
466-- @since 0.6.0
466-- @since 0.6.0
src/Streamly/Internal/Data/Stream/IsStream/Expand.hs+33−27
@@ -89,12 +89,13 @@ module Streamly.Internal.Data.Stream.IsStream.Expand
89
89
90 -- ** Append Many (Unfold)
90 -- ** Append Many (Unfold)
91 -- | Unfold and flatten streams.
91 -- | Unfold and flatten streams.
92+ , unfoldMany
93+ , unfoldManyInterleave
94+ , unfoldManyRoundRobin
92 , concatUnfold
95 , concatUnfold
93− , concatUnfoldInterleave
94− , concatUnfoldRoundrobin
95
96
96 -- ** Interpose
97 -- ** Interpose
97− -- | Insert effects between streams. Like concatUnfold but intersperses an
98+ -- | Insert effects between streams. Like unfoldMany but intersperses an
98 -- effect between the streams. A special case of gintercalate.
99 -- effect between the streams. A special case of gintercalate.
99 , interpose
100 , interpose
100 , interposeSuffix
101 , interposeSuffix
@@ -102,7 +103,7 @@ module Streamly.Internal.Data.Stream.IsStream.Expand
102
103
103 -- ** Intercalate
104 -- ** Intercalate
104 -- | Insert Streams between Streams.
105 -- | Insert Streams between Streams.
105− -- Like concatUnfold but intersperses streams from another source between
106+ -- Like unfoldMany but intersperses streams from another source between
106 -- the streams from the first source.
107 -- the streams from the first source.
107 , intercalate
108 , intercalate
108 , intercalateSuffix
109 , intercalateSuffix
@@ -449,40 +450,45 @@ mergeAsyncByM f m1 m2 =
449 let par = Par.mkParallelD . toStreamD
450 let par = Par.mkParallelD . toStreamD
450 in D.mergeByM f (par m1) (par m2)
451 in D.mergeByM f (par m1) (par m2)
451
452
453+
454+-- @since 0.7.0
455+{-# DEPRECATED concatUnfold "Please use unfoldMany instead." #-}
456+{-# INLINE concatUnfold #-}
457+concatUnfold ::(IsStream t, Monad m) => Unfold m a b -> t m a -> t m b
458+concatUnfold u m = fromStreamD $ D.unfoldMany u (toStreamD m)
459+
452------------------------------------------------------------------------------
460------------------------------------------------------------------------------
453−-- Combine N Streams - concatUnfold
461+-- Combine N Streams - unfoldMany
454------------------------------------------------------------------------------
462------------------------------------------------------------------------------
455
463
456−-- XXX Rename to unfoldMany
457−--
458-- | Like 'concatMap' but uses an 'Unfold' for stream generation. Unlike
464-- | Like 'concatMap' but uses an 'Unfold' for stream generation. Unlike
459-- 'concatMap' this can fuse the 'Unfold' code with the inner loop and
465-- 'concatMap' this can fuse the 'Unfold' code with the inner loop and
460-- therefore provide many times better performance.
466-- therefore provide many times better performance.
461--
467--
462−-- @since 0.7.0
468+-- @since 0.8.0
463−{-# INLINE concatUnfold #-}
469+{-# INLINE unfoldMany #-}
464−concatUnfold ::(IsStream t, Monad m) => Unfold m a b -> t m a -> t m b
470+unfoldMany ::(IsStream t, Monad m) => Unfold m a b -> t m a -> t m b
465−concatUnfold u m = fromStreamD $ D.concatUnfold u (toStreamD m)
471+unfoldMany u m = fromStreamD $ D.unfoldMany u (toStreamD m)
466
472
467−-- | Like 'concatUnfold' but interleaves the streams in the same way as
473+-- | Like 'unfoldMany' but interleaves the streams in the same way as
468-- 'interleave' behaves instead of appending them.
474-- 'interleave' behaves instead of appending them.
469--
475--
470-- /Pre-release/
476-- /Pre-release/
471−{-# INLINE concatUnfoldInterleave #-}
477+{-# INLINE unfoldManyInterleave #-}
472−concatUnfoldInterleave ::(IsStream t, Monad m)
478+unfoldManyInterleave ::(IsStream t, Monad m)
473 => Unfold m a b -> t m a -> t m b
479 => Unfold m a b -> t m a -> t m b
474−concatUnfoldInterleave u m =
480+unfoldManyInterleave u m =
475− fromStreamD $ D.concatUnfoldInterleave u (toStreamD m)
481+ fromStreamD $ D.unfoldManyInterleave u (toStreamD m)
476
482
477−-- | Like 'concatUnfold' but executes the streams in the same way as
483+-- | Like 'unfoldMany' but executes the streams in the same way as
478-- 'roundrobin'.
484-- 'roundrobin'.
479--
485--
480-- /Pre-release/
486-- /Pre-release/
481−{-# INLINE concatUnfoldRoundrobin #-}
487+{-# INLINE unfoldManyRoundRobin #-}
482−concatUnfoldRoundrobin ::(IsStream t, Monad m)
488+unfoldManyRoundRobin ::(IsStream t, Monad m)
483 => Unfold m a b -> t m a -> t m b
489 => Unfold m a b -> t m a -> t m b
484−concatUnfoldRoundrobin u m =
490+unfoldManyRoundRobin u m =
485− fromStreamD $ D.concatUnfoldRoundrobin u (toStreamD m)
491+ fromStreamD $ D.unfoldManyRoundRobin u (toStreamD m)
486
492
487------------------------------------------------------------------------------
493------------------------------------------------------------------------------
488-- Combine N Streams - interpose
494-- Combine N Streams - interpose
@@ -521,11 +527,11 @@ interposeSuffix x unf str =
521------------------------------------------------------------------------------
527------------------------------------------------------------------------------
522
528
523-- XXX we can swap the order of arguments to gintercalate so that the
529-- XXX we can swap the order of arguments to gintercalate so that the
524−-- definition of concatUnfold becomes simpler? The first stream should be
530+-- definition of unfoldMany becomes simpler? The first stream should be
525-- infixed inside the second one. However, if we change the order in
531-- infixed inside the second one. However, if we change the order in
526-- "interleave" as well similarly, then that will make it a bit unintuitive.
532-- "interleave" as well similarly, then that will make it a bit unintuitive.
527--
533--
528−-- > concatUnfold unf str =
534+-- > unfoldMany unf str =
529-- > gintercalate unf str (UF.nilM (\_ -> return ())) (repeat ())
535-- > gintercalate unf str (UF.nilM (\_ -> return ())) (repeat ())
530--
536--
531-- | 'interleaveInfix' followed by unfold and concat.
537-- | 'interleaveInfix' followed by unfold and concat.
@@ -547,7 +553,7 @@ gintercalate unf1 str1 unf2 str2 =
547-- will be starting with the second stream.
553-- will be starting with the second stream.
548
554
549-- > intercalate seed unf str = gintercalate unf str unf (repeatM seed)
555-- > intercalate seed unf str = gintercalate unf str unf (repeatM seed)
550−-- > intercalate a unf str = concatUnfold unf $ intersperse a str
556+-- > intercalate a unf str = unfoldMany unf $ intersperse a str
551--
557--
552-- | 'intersperse' followed by unfold and concat.
558-- | 'intersperse' followed by unfold and concat.
553--
559--
@@ -561,7 +567,7 @@ gintercalate unf1 str1 unf2 str2 =
561intercalate :: (IsStream t, Monad m)
567intercalate :: (IsStream t, Monad m)
562 => b -> Unfold m b c -> t m b -> t m c
568 => b -> Unfold m b c -> t m b -> t m c
563intercalate seed unf str = D.fromStreamD $
569intercalate seed unf str = D.fromStreamD $
564− D.concatUnfold unf $ D.intersperse seed (toStreamD str)
570+ D.unfoldMany unf $ D.intersperse seed (toStreamD str)
565
571
566-- | 'interleaveSuffix' followed by unfold and concat.
572-- | 'interleaveSuffix' followed by unfold and concat.
567--
573--
@@ -576,7 +582,7 @@ gintercalateSuffix unf1 str1 unf2 str2 =
576 unf2 (D.toStreamD str2)
582 unf2 (D.toStreamD str2)
577
583
578-- > intercalateSuffix seed unf str = gintercalateSuffix unf str unf (repeatM seed)
584-- > intercalateSuffix seed unf str = gintercalateSuffix unf str unf (repeatM seed)
579−-- > intercalateSuffix a unf str = concatUnfold unf $ intersperseSuffix a str
585+-- > intercalateSuffix a unf str = unfoldMany unf $ intersperseSuffix a str
580--
586--
581-- | 'intersperseSuffix' followed by unfold and concat.
587-- | 'intersperseSuffix' followed by unfold and concat.
582--
588--
@@ -589,7 +595,7 @@ gintercalateSuffix unf1 str1 unf2 str2 =
589{-# INLINE intercalateSuffix #-}
595{-# INLINE intercalateSuffix #-}
590intercalateSuffix :: (IsStream t, Monad m)
596intercalateSuffix :: (IsStream t, Monad m)
591 => b -> Unfold m b c -> t m b -> t m c
597 => b -> Unfold m b c -> t m b -> t m c
592−intercalateSuffix seed unf str = fromStreamD $ D.concatUnfold unf
598+intercalateSuffix seed unf str = fromStreamD $ D.unfoldMany unf
593 $ D.intersperseSuffix (return seed) (D.toStreamD str)
599 $ D.intersperseSuffix (return seed) (D.toStreamD str)
594
600
595{-
601{-
src/Streamly/Internal/Data/Stream/StreamD/Generate.hs+1−1
@@ -10,7 +10,7 @@
10-- Prefer unfolds ("Streamly.Internal.Data.Unfold") over the combinators in
10-- Prefer unfolds ("Streamly.Internal.Data.Unfold") over the combinators in
11-- this module. They are more powerful and efficient as they can be transformed
11-- this module. They are more powerful and efficient as they can be transformed
12-- and composed on the input side efficiently and they can fuse in nested
12-- and composed on the input side efficiently and they can fuse in nested
13−-- operations (e.g. concatUnfold). All the combinators in this module can be
13+-- operations (e.g. unfoldMany). All the combinators in this module can be
14-- expressed using unfolds with the same efficiency.
14-- expressed using unfolds with the same efficiency.
15--
15--
16-- Operations in this module that are not in "Streamly.Internal.Data.Unfold":
16-- Operations in this module that are not in "Streamly.Internal.Data.Unfold":
src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+18−18
@@ -35,13 +35,13 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
35
35
36 -- *** Appending
36 -- *** Appending
37 -- | Append a stream after another. A special case of concatMap or
37 -- | Append a stream after another. A special case of concatMap or
38− -- concatUnfold.
38+ -- unfoldMany.
39 AppendState(..)
39 AppendState(..)
40 , append
40 , append
41
41
42 -- *** Interleaving
42 -- *** Interleaving
43 -- | Interleave elements from two streams alternately. A special case of
43 -- | Interleave elements from two streams alternately. A special case of
44− -- concatUnfoldInterleave.
44+ -- unfoldManyInterleave.
45 , InterleaveState(..)
45 , InterleaveState(..)
46 , interleave
46 , interleave
47 , interleaveMin
47 , interleaveMin
@@ -51,7 +51,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
51 -- *** Scheduling
51 -- *** Scheduling
52 -- | Execute streams alternately irrespective of whether they generate
52 -- | Execute streams alternately irrespective of whether they generate
53 -- elements or not. Note 'interleave' would execute a stream until it
53 -- elements or not. Note 'interleave' would execute a stream until it
54− -- yields an element. A special case of concatUnfoldRoundrobin.
54+ -- yields an element. A special case of unfoldManyRoundRobin.
55 , roundRobin -- interleaveFair?/ParallelFair
55 , roundRobin -- interleaveFair?/ParallelFair
56
56
57 -- *** Zipping
57 -- *** Zipping
@@ -70,7 +70,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
70 -- @
70 -- @
71 -- concat: f (t m a) -> t m a
71 -- concat: f (t m a) -> t m a
72 -- concatMap: (a -> t m b) -> t m a -> t m b
72 -- concatMap: (a -> t m b) -> t m a -> t m b
73− -- concatUnfold: Unfold m a b -> t m a -> t m b
73+ -- unfoldMany: Unfold m a b -> t m a -> t m b
74 -- @
74 -- @
75
75
76 -- *** ConcatMap
76 -- *** ConcatMap
@@ -83,19 +83,19 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
83 -- | Generate streams by using an unfold on each element of an input
83 -- | Generate streams by using an unfold on each element of an input
84 -- stream, append the resulting streams and flatten. A special case of
84 -- stream, append the resulting streams and flatten. A special case of
85 -- gintercalate.
85 -- gintercalate.
86− , concatUnfold
86+ , unfoldMany
87 , ConcatUnfoldInterleaveState (..)
87 , ConcatUnfoldInterleaveState (..)
88− , concatUnfoldInterleave
88+ , unfoldManyInterleave
89− , concatUnfoldRoundrobin
89+ , unfoldManyRoundRobin
90
90
91 -- *** Interpose
91 -- *** Interpose
92− -- | Like concatUnfold but intersperses an effect between the streams. A
92+ -- | Like unfoldMany but intersperses an effect between the streams. A
93 -- special case of gintercalate.
93 -- special case of gintercalate.
94 , interpose
94 , interpose
95 , interposeSuffix
95 , interposeSuffix
96
96
97 -- *** Intercalate
97 -- *** Intercalate
98− -- | Like concatUnfold but intersperses streams from another source between
98+ -- | Like unfoldMany but intersperses streams from another source between
99 -- the streams from the first source.
99 -- the streams from the first source.
100 , gintercalate
100 , gintercalate
101 , gintercalateSuffix
101 , gintercalateSuffix
@@ -116,7 +116,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
116
116
117 -- ** Parsing
117 -- ** Parsing
118 -- | Parsing is opposite to flattening. 'parseMany' is dual to concatMap or
118 -- | Parsing is opposite to flattening. 'parseMany' is dual to concatMap or
119− -- concatUnfold. concatMap generates a stream from single values in a
119+ -- unfoldMany. concatMap generates a stream from single values in a
120 -- stream and flattens, parseMany does the opposite of flattening by
120 -- stream and flattens, parseMany does the opposite of flattening by
121 -- splitting the stream and then folds each such split to single value in
121 -- splitting the stream and then folds each such split to single value in
122 -- the output stream.
122 -- the output stream.
@@ -477,7 +477,7 @@ mergeBy
477mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
477mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
478
478
479------------------------------------------------------------------------------
479------------------------------------------------------------------------------
480−-- Combine N Streams - concatUnfold
480+-- Combine N Streams - unfoldMany
481------------------------------------------------------------------------------
481------------------------------------------------------------------------------
482
482
483data ConcatUnfoldInterleaveState o i =
483data ConcatUnfoldInterleaveState o i =
@@ -502,9 +502,9 @@ data ConcatUnfoldInterleaveState o i =
502-- Ideally, we need some scheduling bias to inner streams vs outer stream.
502-- Ideally, we need some scheduling bias to inner streams vs outer stream.
503-- Maybe we can configure the behavior.
503-- Maybe we can configure the behavior.
504--
504--
505−{-# INLINE_NORMAL concatUnfoldInterleave #-}
505+{-# INLINE_NORMAL unfoldManyInterleave #-}
506−concatUnfoldInterleave :: Monad m => Unfold m a b -> Stream m a -> Stream m b
506+unfoldManyInterleave :: Monad m => Unfold m a b -> Stream m a -> Stream m b
507−concatUnfoldInterleave (Unfold istep inject) (Stream ostep ost) =
507+unfoldManyInterleave (Unfold istep inject) (Stream ostep ost) =
508 Stream step (ConcatUnfoldInterleaveOuter ost [])
508 Stream step (ConcatUnfoldInterleaveOuter ost [])
509 where
509 where
510 {-# INLINE_LATE step #-}
510 {-# INLINE_LATE step #-}
@@ -553,11 +553,11 @@ concatUnfoldInterleave (Unfold istep inject) (Stream ostep ost) =
553--
553--
554-- This could be inefficient if the tasks are too small.
554-- This could be inefficient if the tasks are too small.
555--
555--
556−-- Compared to concatUnfoldInterleave this one switches streams on Skips.
556+-- Compared to unfoldManyInterleave this one switches streams on Skips.
557--
557--
558−{-# INLINE_NORMAL concatUnfoldRoundrobin #-}
558+{-# INLINE_NORMAL unfoldManyRoundRobin #-}
559−concatUnfoldRoundrobin :: Monad m => Unfold m a b -> Stream m a -> Stream m b
559+unfoldManyRoundRobin :: Monad m => Unfold m a b -> Stream m a -> Stream m b
560−concatUnfoldRoundrobin (Unfold istep inject) (Stream ostep ost) =
560+unfoldManyRoundRobin (Unfold istep inject) (Stream ostep ost) =
561 Stream step (ConcatUnfoldInterleaveOuter ost [])
561 Stream step (ConcatUnfoldInterleaveOuter ost [])
562 where
562 where
563 {-# INLINE_LATE step #-}
563 {-# INLINE_LATE step #-}
src/Streamly/Internal/Data/Stream/StreamD/Transform.hs+1−1
@@ -1129,7 +1129,7 @@ reverse' m = Stream step Nothing
1129 return $ Yield x (Just (start, next))
1129 return $ Yield x (Just (start, next))
1130-}
1130-}
1131reverse' =
1131reverse' =
1132− A.flattenArraysRev -- concatUnfold A.readRev
1132+ A.flattenArraysRev -- unfoldMany A.readRev
1133 . fromStreamK
1133 . fromStreamK
1134 . K.reverse
1134 . K.reverse
1135 . toStreamK
1135 . toStreamK
src/Streamly/Internal/Data/Stream/StreamD/Type.hs+7−7
@@ -75,7 +75,7 @@ module Streamly.Internal.Data.Stream.StreamD.Type
75
75
76 -- * Nesting
76 -- * Nesting
77 , ConcatMapUState (..)
77 , ConcatMapUState (..)
78− , concatUnfold
78+ , unfoldMany
79 , concatMap
79 , concatMap
80 , concatMapM
80 , concatMapM
81 , FoldMany (..) -- for inspection testing
81 , FoldMany (..) -- for inspection testing
@@ -690,7 +690,7 @@ instance Applicative f => Applicative (Stream f) where
690 (<*) = apDiscardSnd
690 (<*) = apDiscardSnd
691
691
692------------------------------------------------------------------------------
692------------------------------------------------------------------------------
693−-- Combine N Streams - concatUnfold
693+-- Combine N Streams - unfoldMany
694------------------------------------------------------------------------------
694------------------------------------------------------------------------------
695
695
696-- Define a unique structure to use in inspection testing
696-- Define a unique structure to use in inspection testing
@@ -698,7 +698,7 @@ data ConcatMapUState o i =
698 ConcatMapUOuter o
698 ConcatMapUOuter o
699 | ConcatMapUInner o i
699 | ConcatMapUInner o i
700
700
701−-- | @concatUnfold unfold stream@ uses @unfold@ to map the input stream elements
701+-- | @unfoldMany unfold stream@ uses @unfold@ to map the input stream elements
702-- to streams and then flattens the generated streams into a single output
702-- to streams and then flattens the generated streams into a single output
703-- stream.
703-- stream.
704
704
@@ -707,9 +707,9 @@ data ConcatMapUState o i =
707-- optimization via fusion. This can be many times more efficient than
707-- optimization via fusion. This can be many times more efficient than
708-- 'concatMap'.
708-- 'concatMap'.
709
709
710−{-# INLINE_NORMAL concatUnfold #-}
710+{-# INLINE_NORMAL unfoldMany #-}
711−concatUnfold :: Monad m => Unfold m a b -> Stream m a -> Stream m b
711+unfoldMany :: Monad m => Unfold m a b -> Stream m a -> Stream m b
712−concatUnfold (Unfold istep inject) (Stream ostep ost) =
712+unfoldMany (Unfold istep inject) (Stream ostep ost) =
713 Stream step (ConcatMapUOuter ost)
713 Stream step (ConcatMapUOuter ost)
714 where
714 where
715 {-# INLINE_LATE step #-}
715 {-# INLINE_LATE step #-}
@@ -728,7 +728,7 @@ concatUnfold (Unfold istep inject) (Stream ostep ost) =
728 Yield x i' -> Yield x (ConcatMapUInner o i')
728 Yield x i' -> Yield x (ConcatMapUInner o i')
729 Skip i' -> Skip (ConcatMapUInner o i')
729 Skip i' -> Skip (ConcatMapUInner o i')
730 Stop -> Skip (ConcatMapUOuter o)
730 Stop -> Skip (ConcatMapUOuter o)
731−
731+
732------------------------------------------------------------------------------
732------------------------------------------------------------------------------
733-- Combine N Streams - concatMap
733-- Combine N Streams - concatMap
734------------------------------------------------------------------------------
734------------------------------------------------------------------------------
src/Streamly/Internal/Data/Stream/StreamK/Type.hs+1−1
@@ -1181,7 +1181,7 @@ instance Monad m => Monad (Stream m) where
1181
1181
1182{-
1182{-
1183-- Like concatMap but generates stream using an unfold function. Similar to
1183-- Like concatMap but generates stream using an unfold function. Similar to
1184−-- concatUnfold but for StreamK.
1184+-- unfoldMany but for StreamK.
1185concatUnfoldr :: IsStream t
1185concatUnfoldr :: IsStream t
1186 => (b -> t m (Maybe (a, b))) -> t m b -> t m a
1186 => (b -> t m (Maybe (a, b))) -> t m b -> t m a
1187concatUnfoldr = undefined
1187concatUnfoldr = undefined
src/Streamly/Internal/Data/Unfold.hs+3−3
@@ -17,13 +17,13 @@
17--
17--
18-- This allows an important optimization to occur in several cases, making the
18-- This allows an important optimization to occur in several cases, making the
19-- 'Unfold' a more efficient abstraction. Consider the 'concatMap' and
19-- 'Unfold' a more efficient abstraction. Consider the 'concatMap' and
20−-- 'concatUnfold' operations, the latter is more efficient. 'concatMap'
20+-- 'unfoldMany' operations, the latter is more efficient. 'concatMap'
21-- generates a new stream object from each element in the stream by applying
21-- generates a new stream object from each element in the stream by applying
22-- the supplied function to the element, the stream object includes the "step"
22-- the supplied function to the element, the stream object includes the "step"
23-- function as well as the initial "state" of the stream. Since the stream is
23-- function as well as the initial "state" of the stream. Since the stream is
24-- generated dynamically the compiler does not know the step function or the
24-- generated dynamically the compiler does not know the step function or the
25-- state type statically at compile time, therefore, it cannot inline it. On
25-- state type statically at compile time, therefore, it cannot inline it. On
26−-- the other hand in case of 'concatUnfold' the compiler has visibility into
26+-- the other hand in case of 'unfoldMany' the compiler has visibility into
27-- the unfold's state generation function, therefore, the compiler knows all
27-- the unfold's state generation function, therefore, the compiler knows all
28-- the types statically and it can inline the inject as well as the step
28-- the types statically and it can inline the inject as well as the step
29-- functions, generating efficient code. Essentially, the stream is not opaque
29-- functions, generating efficient code. Essentially, the stream is not opaque
@@ -844,7 +844,7 @@ fromProducer = Unfold step (return . FromSVarRead)
844-- stream.
844-- stream.
845--
845--
846-- @
846-- @
847−-- S.mapM_ print $ S.concatUnfold (UF.teeZipWith (,) UF.identity (UF.singleton sqrt)) $ S.fromList [1..10]
847+-- S.mapM_ print $ S.unfoldMany (UF.teeZipWith (,) UF.identity (UF.singleton sqrt)) $ S.fromList [1..10]
848-- @
848-- @
849--
849--
850-- /Pre-release/
850-- /Pre-release/
src/Streamly/Internal/Data/Unfold/Type.hs+1−1
@@ -352,7 +352,7 @@ zipWithM f (Unfold step1 inject1) (Unfold step2 inject2) = Unfold step inject
352--
352--
353-- @
353-- @
354-- S.mapM_ print
354-- S.mapM_ print
355−-- $ S.concatUnfold (UF.zipWith (,) UF.identity (UF.singleton sqrt))
355+-- $ S.unfoldMany (UF.zipWith (,) UF.identity (UF.singleton sqrt))
356-- $ S.map (\x -> (x,x))
356-- $ S.map (\x -> (x,x))
357-- $ S.fromList [1..10]
357-- $ S.fromList [1..10]
358-- @
358-- @
src/Streamly/Prelude.hs+1
@@ -596,6 +596,7 @@ module Streamly.Prelude
596 , concatMap
596 , concatMap
597 , concatMapM
597 , concatMapM
598 , concatUnfold
598 , concatUnfold
599+ , unfoldMany
599
600
600 -- ** Folding Containers of Streams
601 -- ** Folding Containers of Streams
601 -- | These are variants of standard 'Foldable' fold functions that use a
602 -- | These are variants of standard 'Foldable' fold functions that use a
test/Streamly/Test/Common/Array.hs+1−1
@@ -163,7 +163,7 @@ testArraysOf =
163 monadicIO $ do
163 monadicIO $ do
164 xs <- run
164 xs <- run
165 $ S.toList
165 $ S.toList
166− $ S.concatUnfold A.read
166+ $ S.unfoldMany A.read
167 $ arraysOf 240
167 $ arraysOf 240
168 $ S.fromList list
168 $ S.fromList list
169 assert (xs == list)
169 assert (xs == list)
test/Streamly/Test/Data/Parser/ParserD.hs+1−1
@@ -630,7 +630,7 @@ parseUnfold = do
630 Producer.simplify (Source.parseManyD parser readSrc)
630 Producer.simplify (Source.parseManyD parser readSrc)
631 xs <- run
631 xs <- run
632 $ S.toList
632 $ S.toList
633− $ S.concatUnfold Unfold.fromList
633+ $ S.unfoldMany Unfold.fromList
634 $ S.unfold streamParser src
634 $ S.unfold streamParser src
635
635
636 listEquals (==) xs ls
636 listEquals (==) xs ls
test/lib/Streamly/Test/Prelude/Common.hs+2−2
@@ -1198,10 +1198,10 @@ transformCombineOpsCommon constr desc eq t = do
1198 forAll (choose (0, 100)) $ \n ->
1198 forAll (choose (0, 100)) $ \n ->
1199 transform (concatMap (const [1..n]))
1199 transform (concatMap (const [1..n]))
1200 t (S.concatMapM (const (return $ S.fromList [1..n])))
1200 t (S.concatMapM (const (return $ S.fromList [1..n])))
1201− prop (desc <> " concatUnfold") $
1201+ prop (desc <> " unfoldMany") $
1202 forAll (choose (0, 100)) $ \n ->
1202 forAll (choose (0, 100)) $ \n ->
1203 transform (concatMap (const [1..n]))
1203 transform (concatMap (const [1..n]))
1204− t (S.concatUnfold (UF.lmap (const undefined)
1204+ t (S.unfoldMany (UF.lmap (const undefined)
1205 $ UF.supply UF.fromList [1..n]))
1205 $ UF.supply UF.fromList [1..n]))
1206
1206
1207toListFL :: Monad m => FL.Fold m a [a]
1207toListFL :: Monad m => FL.Fold m a [a]