@@ -95,6 +95,10 @@ module Streamly.Data.Stream
95 -- versions provided in this module can be much more efficient in most
95 -- versions provided in this module can be much more efficient in most
96 -- cases. Users can create custom combinators using these primitives.
96 -- cases. Users can create custom combinators using these primitives.
100+ -- , cons2 -- fused version
101+ -- , consM2 -- fused version
99 -- ** Unfolding
103 -- ** Unfolding
100 -- | Generalized way of generating a stream efficiently.
104 -- | Generalized way of generating a stream efficiently.
@@ -142,143 +146,12 @@ module Streamly.Data.Stream
142 -- using the corresponding unfolds in the "Streamly.Data.Unfold" module.
146 -- using the corresponding unfolds in the "Streamly.Data.Unfold" module.
143 , unfold -- XXX rename to fromUnfold?
147 , unfold -- XXX rename to fromUnfold?
145− -- * Expanding
149+ -- * Elimination
146− -- | Operations that increase the size of a stream by adding one or more
150+ -- | Functions ending in the general shape @Stream m a -> m b@ or @Stream m
147− -- elements to it.
151+ -- a -> m (b, Stream m a)@
149− -- See also: "Streamly.Internal.Data.Stream.Expand" for
150− -- @Pre-release@ functions.
152− -- ** Consing Elements
155− -- , cons2 -- fused version
156− -- , consM2 -- fused version
158− -- ** Inserting Elements
159− -- | Inserting elements is a special case of interleaving/merging streams.
172− , wSerial -- XXX rename to interleaveWeighted
175− -- | Merging of @n@ streams can be performed by combining the streams pair
177− -- 'Streamly.Internal.Data.Stream.IsStream.Expand.concatPairsWith' to give
178− -- O(n * log n) time complexity.
179− -- If used with 'concatMapWith' it will have O(n^2) performance.
186− -- ** Nested Unfolds
191− -- ** Nested Streams
192− -- | Stream operations like map and filter represent loop processing in
193− -- imperative programming terms. Similarly, the imperative concept of
194− -- nested loops are represented by streams of streams. The 'concatMap'
195− -- operation represents nested looping.
196− -- A 'concatMap' operation loops over the input stream and then for each
197− -- element of the input stream generates another stream and then loops over
198− -- that inner stream as well producing effects and generating a single
200− -- The 'Monad' instances of different stream types provide a more
201− -- convenient way of writing nested loops. Note that the monad bind
202− -- operation is just @flip concatMap@.
204− -- One dimension loops are just a special case of nested loops. For
205− -- example, 'concatMap' can degenerate to a simple map operation:
207− -- > map f m = S.concatMap (\x -> S.fromPure (f x)) m
209− -- Similarly, 'concatMap' can perform filtering by mapping an element to a
212− -- > filter p m = S.concatMap (\x -> if p x then S.fromPure x else S.nil) m
220− -- | One-to-one transformations not changing the size (almost) of the
223− -- See also: "Streamly.Internal.Data.Stream.Transform" for
224− -- @Pre-release@ functions.
227− -- | Stateless one-to-one transformations. Use 'fmap' for mapping a pure
228− -- function on a stream.
231− -- In imperative terms a map operation can be considered as a loop over
232− -- the stream that transforms the stream into another stream by performing
233− -- an operation on each element of the stream.
235− -- 'map' is the least powerful transformation operation with strictest
236− -- guarantees. A map, (1) is a stateless loop which means that no state is
237− -- allowed to be carried from one iteration to another, therefore,
238− -- operations on different elements are guaranteed to not affect each
239− -- other, (2) is a strictly one-to-one transformation of stream elements
240− -- which means it guarantees that no elements can be added or removed from
241− -- the stream, it can merely transform them.
245− -- ** Mapping Side Effects
246− -- , trace -- XXX Use "tracing" map instead?
251− -- | Stateful one-to-one transformations.
254− -- XXX postscan1 can be implemented using Monoids or Refolds.
257− -- | Indexing can be considered as a special type of zipping where we zip a
258− -- stream with an index stream.
262− -- ** Reordering Elements
266− -- | Zipping of @n@ streams can be performed by combining the streams pair
268− -- 'Streamly.Internal.Data.Stream.IsStream.Expand.concatPairsWith' with
269− -- O(n * log n) time complexity.
270− -- If used with 'concatMapWith' it will have O(n^2) performance.
277− -- | Operations that reduce the size of a stream by removing some or all
278− -- elements from it.
280− -- See also: "Streamly.Internal.Data.Stream.Reduce" and
281− -- "Streamly.Internal.Data.Stream.Eliminate" for @Pre-release@ functions.
153+ -- See also: "Streamly.Internal.Data.Stream.Eliminate" for @Pre-release@
283-- EXPLANATION: In imperative terms a fold can be considered as a loop over the stream
156-- EXPLANATION: In imperative terms a fold can be considered as a loop over the stream
284-- that reduces the stream to a single value.
157-- that reduces the stream to a single value.
@@ -347,13 +220,78 @@ module Streamly.Data.Stream
347-- the previous step. However, it is possible to fold parts of the stream in
220-- the previous step. However, it is possible to fold parts of the stream in
348-- parallel and then combine the results using a monoid.
221-- parallel and then combine the results using a monoid.
350− -- ** Unconsing
223+ -- ** Primitives
224+ -- Consuming a part of the stream and returning the rest. Functions
225+ -- ending in the general shape @Stream m a -> m (b, Stream m a)@
353− -- ** Filter Map
228+ -- ** Folding
354− -- | Stateless filters. Remove some elements from the stream based on a
229+ , fold -- XXX rename to run? We can have a Stream.run and Fold.run.
355− -- predicate.
230+ -- XXX fold1 can be achieved using Monoids or Refolds.
238+ -- -- ** Lazy Right Folds
239+ -- Consuming a stream to build a right associated expression, suitable
240+ -- for lazy evaluation. Evaluation of the input happens when the output of
241+ -- the fold is evaluated, the fold output is a lazy thunk.
243+ -- This is suitable for stream transformation operations, for example,
244+ -- operations like mapping a function over the stream.
249+ -- | Stateless one-to-one transformations. Use 'fmap' for mapping a pure
250+ -- function on a stream.
253+ -- In imperative terms a map operation can be considered as a loop over
254+ -- the stream that transforms the stream into another stream by performing
255+ -- an operation on each element of the stream.
257+ -- 'map' is the least powerful transformation operation with strictest
258+ -- guarantees. A map, (1) is a stateless loop which means that no state is
259+ -- allowed to be carried from one iteration to another, therefore,
260+ -- operations on different elements are guaranteed to not affect each
261+ -- other, (2) is a strictly one-to-one transformation of stream elements
262+ -- which means it guarantees that no elements can be added or removed from
263+ -- the stream, it can merely transform them.
266+ -- , trace -- XXX Use "tracing" map instead?
271+ -- | Stateful one-to-one transformations.
273+ -- See also: "Streamly.Internal.Data.Stream.Transform" for
274+ -- @Pre-release@ functions.
277+ -- XXX postscan1 can be implemented using Monoids or Refolds.
278+ -- Indexing can be considered as a special type of zipping where we zip a
279+ -- stream with an index stream.
284+ -- | Add elements to the stream.
286+ -- Inserting elements is a special case of interleaving/merging streams.
292+ -- | Remove elements from the stream.
294+ -- ** Stateless Filters
357 -- EXPLANATION:
295 -- EXPLANATION:
358 -- In imperative terms a filter over a stream corresponds to a loop with a
296 -- In imperative terms a filter over a stream corresponds to a loop with a
359 -- @continue@ clause for the cases when the predicate fails.
297 -- @continue@ clause for the cases when the predicate fails.
@@ -363,8 +301,7 @@ module Streamly.Data.Stream
364 , filterM
302 , filterM
367− -- | Stateful filters.
304+ -- ** Stateful Filters
369 , takeWhile
306 , takeWhile
370 , takeWhileM
307 , takeWhileM
@@ -375,52 +312,87 @@ module Streamly.Data.Stream
377 -- ** Searching
314 -- ** Searching
378− -- | Finding the presence or location of an element, a sequence of elements
315+ -- Finding the presence or location of an element, a sequence of elements
379 -- or another stream within a stream.
316 -- or another stream within a stream.
381 -- -- ** Searching Elements
318 -- -- ** Searching Elements
382 , findIndices
319 , findIndices
383 , elemIndices
320 , elemIndices
385− -- ** Splitting
322+ -- * Combining Two Streams
386− -- | Consuming a part of the stream and returning the rest. Functions
323+ -- ** Appending
387− -- ending in the general shape @Stream m a -> m (b, Stream m a)@
324+ , append
388− , foldBreak
325+ , append2
330+ , wSerial -- XXX rename to interleaveWeighted
333+ -- | Merging of @n@ streams can be performed by combining the streams pair
335+ -- 'Streamly.Internal.Data.Stream.IsStream.Expand.concatPairsWith' to give
336+ -- O(n * log n) time complexity.
337+ -- If used with 'concatMapWith' it will have O(n^2) performance.
391− -- ** Elimination
344+ -- ** Zipping
392− -- | Functions ending in the general shape @Stream m a -> m b@
345+ -- | Zipping of @n@ streams can be performed by combining the streams pair
393− -- Consuming the stream entirely or partially, discarding the rest.
346+ -- wise using
347+ -- 'Streamly.Internal.Data.Stream.IsStream.Expand.concatPairsWith' with
348+ -- O(n * log n) time complexity.
349+ -- If used with 'concatMapWith' it will have O(n^2) performance.
360+ -- * Stream of streams
361+ -- | Stream operations like map and filter represent loop processing in
362+ -- imperative programming terms. Similarly, the imperative concept of
363+ -- nested loops are represented by streams of streams. The 'concatMap'
364+ -- operation represents nested looping.
365+ -- A 'concatMap' operation loops over the input stream and then for each
366+ -- element of the input stream generates another stream and then loops over
367+ -- that inner stream as well producing effects and generating a single
369+ -- The 'Monad' instances of different stream types provide a more
370+ -- convenient way of writing nested loops. Note that the monad bind
371+ -- operation is just @flip concatMap@.
395− -- Strict left folds consume a stream and build a left associated
373+ -- One dimension loops are just a special case of nested loops. For
396− -- expression, suitable for incremental/strict evaluation. Evaluation of
374+ -- example, 'concatMap' can degenerate to a simple map operation:
397− -- the input happens when the fold runs, the fold output is fully
398− -- evaluated. A fold can terminate without consuming the entire stream.
400− -- This is suitable for reduction operations, for example, operations like
376+ -- > map f m = S.concatMap (\x -> S.fromPure (f x)) m
401− -- summing the stream. See "Streamly.Data.Fold" for an overview of
402− -- composable left folds. Parsers (See "Streamly.Internal.Data.Parser") are
403− -- more powerful folds that add backtracking and error functionality to
404− -- terminating folds.
406− , fold -- XXX rename to run? We can have a Stream.run and Fold.run.
378+ -- Similarly, 'concatMap' can perform filtering by mapping an element to a
407− -- XXX fold1 can be achieved using Monoids or Refolds.
379+ -- 'nil' stream:
409−
381+ -- > filter p m = S.concatMap (\x -> if p x then S.fromPure x else S.nil) m
410− -- -- ** Lazy Right Folds
411− -- Consuming a stream to build a right associated expression, suitable
412− -- for lazy evaluation. Evaluation of the input happens when the output of
413− -- the fold is evaluated, the fold output is a lazy thunk.
415− -- This is suitable for stream transformation operations, for example,
416− -- operations like mapping a function over the stream.
420− -- ** Nested Folds
384+ , concatMapWith
421− , foldMany
389+ , foldMany -- XXX Rename to foldRepeat
391+ -- * Buffered Operations
392+ -- | Operations that require buffering of the stream.
423− -- ** Multi-Stream folds
395+ -- * Multi-Stream folds
424 -- | Operations that consume multiple streams at the same time.
396 -- | Operations that consume multiple streams at the same time.