on master help sign in
Tweak the organization of Data.Stream API exports
commitf41b53e07e3860b400e61195af966bf95cd3050c authorHarendra Kumar <harendra@composewell.com> dateTue 23 Aug 2022, 15:12 (4 years ago) parent7278ecb
2 files changed+151−177
core/src/Streamly/Data/Stream.hs+147−175 core/src/Streamly/Internal/Data/Stream/Eliminate.hs+4−2
core/src/Streamly/Data/Stream.hs+147−175
@@ -95,6 +95,10 @@ module Streamly.Data.Stream
9595 -- versions provided in this module can be much more efficient in most
9696 -- cases. Users can create custom combinators using these primitives.
9797 , nil
98+ , cons
99+ , consM
100+ -- , cons2 -- fused version
101+ -- , consM2 -- fused version
98102
99103 -- ** Unfolding
100104 -- | Generalized way of generating a stream efficiently.
@@ -142,143 +146,12 @@ module Streamly.Data.Stream
142146 -- using the corresponding unfolds in the "Streamly.Data.Unfold" module.
143147 , unfold -- XXX rename to fromUnfold?
144148
145− -- * Expanding
146− -- | Operations that increase the size of a stream by adding one or more
147− -- elements to it.
148− --
149− -- See also: "Streamly.Internal.Data.Stream.Expand" for
150− -- @Pre-release@ functions.
151−
152− -- ** Consing Elements
153− , cons
154− , consM
155− -- , cons2 -- fused version
156− -- , consM2 -- fused version
157−
158− -- ** Inserting Elements
159− -- | Inserting elements is a special case of interleaving/merging streams.
160−
161− , insertBy
162− , intersperseM
163− , intersperse
164−
165− -- ** Appending
166− , append
167− , append2
168−
169− -- ** Interleaving
170− -- , interleave
171− -- , interleave2
172− , wSerial -- XXX rename to interleaveWeighted
173−
174− -- ** Merging
175− -- | Merging of @n@ streams can be performed by combining the streams pair
176− -- wise using
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.
180−
181− , mergeBy
182− , mergeByM
183− -- , mergeBy2
184− -- , mergeByM2
185−
186− -- ** Nested Unfolds
187− , unfoldMany
188− , intercalate
189− , intercalateSuffix
190−
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
199− -- output stream.
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@.
203− --
204− -- One dimension loops are just a special case of nested loops. For
205− -- example, 'concatMap' can degenerate to a simple map operation:
206− --
207− -- > map f m = S.concatMap (\x -> S.fromPure (f x)) m
208− --
209− -- Similarly, 'concatMap' can perform filtering by mapping an element to a
210− -- 'nil' stream:
211− --
212− -- > filter p m = S.concatMap (\x -> if p x then S.fromPure x else S.nil) m
149+ -- * Elimination
150+ -- | Functions ending in the general shape @Stream m a -> m b@ or @Stream m
151+ -- a -> m (b, Stream m a)@
213152 --
214−
215− , concatMapWith
216− , concatMap
217− , concatMapM
218−
219− -- * Scanning
220− -- | One-to-one transformations not changing the size (almost) of the
221− -- stream.
222− --
223− -- See also: "Streamly.Internal.Data.Stream.Transform" for
224− -- @Pre-release@ functions.
225−
226− -- ** Mapping
227− -- | Stateless one-to-one transformations. Use 'fmap' for mapping a pure
228− -- function on a stream.
229−
230− -- EXPLANATION:
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.
234− --
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.
242− , sequence
243− , mapM
244−
245− -- ** Mapping Side Effects
246− -- , trace -- XXX Use "tracing" map instead?
247− , tap
248− , delay
249−
250− -- ** Scanning
251− -- | Stateful one-to-one transformations.
252− , scan
253− , postscan
254− -- XXX postscan1 can be implemented using Monoids or Refolds.
255−
256− -- ** Indexing
257− -- | Indexing can be considered as a special type of zipping where we zip a
258− -- stream with an index stream.
259− , indexed
260− , indexedR
261−
262− -- ** Reordering Elements
263− , reverse
264−
265− -- ** Zipping
266− -- | Zipping of @n@ streams can be performed by combining the streams pair
267− -- wise using
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.
271− , zipWith
272− , zipWithM
273− -- , zipWith2
274− -- , zipWithM2
275−
276− -- * Reducing
277− -- | Operations that reduce the size of a stream by removing some or all
278− -- elements from it.
279− --
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@
154+ -- functions.
282155
283156-- EXPLANATION: In imperative terms a fold can be considered as a loop over the stream
284157-- that reduces the stream to a single value.
@@ -347,13 +220,78 @@ module Streamly.Data.Stream
347220-- the previous step. However, it is possible to fold parts of the stream in
348221-- parallel and then combine the results using a monoid.
349222
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)@
351226 , uncons
352227
353− -- ** Filter Map
354− -- | Stateless filters. Remove some elements from the stream based on a
355− -- predicate.
228+ -- ** Folding
229+ , fold -- XXX rename to run? We can have a Stream.run and Fold.run.
230+ -- XXX fold1 can be achieved using Monoids or Refolds.
231+ , foldBreak
232+ , foldContinue
356233
234+ -- ** Parsing
235+ , parse
236+ , parseBreak
237+
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.
242+ --
243+ -- This is suitable for stream transformation operations, for example,
244+ -- operations like mapping a function over the stream.
245+ -- , foldrM
246+ -- , foldr
247+
248+ -- * Mapping
249+ -- | Stateless one-to-one transformations. Use 'fmap' for mapping a pure
250+ -- function on a stream.
251+
252+ -- EXPLANATION:
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.
256+ --
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.
264+ , sequence
265+ , mapM
266+ -- , trace -- XXX Use "tracing" map instead?
267+ , tap
268+ , delay
269+
270+ -- * Scanning
271+ -- | Stateful one-to-one transformations.
272+ --
273+ -- See also: "Streamly.Internal.Data.Stream.Transform" for
274+ -- @Pre-release@ functions.
275+ , scan
276+ , postscan
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.
280+ , indexed
281+ , indexedR
282+
283+ -- * Insertion
284+ -- | Add elements to the stream.
285+
286+ -- Inserting elements is a special case of interleaving/merging streams.
287+ , insertBy
288+ , intersperseM
289+ , intersperse
290+
291+ -- * Filtering
292+ -- | Remove elements from the stream.
293+
294+ -- ** Stateless Filters
357295 -- EXPLANATION:
358296 -- In imperative terms a filter over a stream corresponds to a loop with a
359297 -- @continue@ clause for the cases when the predicate fails.
@@ -363,8 +301,7 @@ module Streamly.Data.Stream
363301 , filter
364302 , filterM
365303
366− -- ** Filter Scans
367− -- | Stateful filters.
304+ -- ** Stateful Filters
368305 , take
369306 , takeWhile
370307 , takeWhileM
@@ -375,52 +312,87 @@ module Streamly.Data.Stream
375312 , uniq
376313
377314 -- ** 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
379316 -- or another stream within a stream.
380317
381318 -- -- ** Searching Elements
382319 , findIndices
383320 , elemIndices
384321
385− -- ** Splitting
386− -- | Consuming a part of the stream and returning the rest. Functions
387− -- ending in the general shape @Stream m a -> m (b, Stream m a)@
388− , foldBreak
389− , parseBreak
322+ -- * Combining Two Streams
323+ -- ** Appending
324+ , append
325+ , append2
326+
327+ -- ** Interleaving
328+ -- , interleave
329+ -- , interleave2
330+ , wSerial -- XXX rename to interleaveWeighted
331+
332+ -- ** Merging
333+ -- | Merging of @n@ streams can be performed by combining the streams pair
334+ -- wise using
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.
338+
339+ , mergeBy
340+ , mergeByM
341+ -- , mergeBy2
342+ -- , mergeByM2
390343
391− -- ** Elimination
392− -- | Functions ending in the general shape @Stream m a -> m b@
393− -- Consuming the stream entirely or partially, discarding the rest.
344+ -- ** Zipping
345+ -- | Zipping of @n@ streams can be performed by combining the streams pair
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.
350+ , zipWith
351+ , zipWithM
352+ -- , zipWith2
353+ -- , zipWithM2
354+
355+ -- * Unfold Each
356+ , unfoldMany
357+ , intercalate
358+ , intercalateSuffix
359+
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
368+ -- output stream.
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@.
394372 --
395− -- Strict left folds consume a stream and build a left associated
396− -- expression, suitable for incremental/strict evaluation. Evaluation of
397− -- the input happens when the fold runs, the fold output is fully
398− -- evaluated. A fold can terminate without consuming the entire stream.
373+ -- One dimension loops are just a special case of nested loops. For
374+ -- example, 'concatMap' can degenerate to a simple map operation:
399375 --
400− -- This is suitable for reduction operations, for example, operations like
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.
376+ -- > map f m = S.concatMap (\x -> S.fromPure (f x)) m
405377 --
406− , fold -- XXX rename to run? We can have a Stream.run and Fold.run.
407− -- XXX fold1 can be achieved using Monoids or Refolds.
408− , parse
409−
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.
378+ -- Similarly, 'concatMap' can perform filtering by mapping an element to a
379+ -- 'nil' stream:
380+ --
381+ -- > filter p m = S.concatMap (\x -> if p x then S.fromPure x else S.nil) m
414382 --
415− -- This is suitable for stream transformation operations, for example,
416− -- operations like mapping a function over the stream.
417− -- , foldrM
418− -- , foldr
419383
420− -- ** Nested Folds
421− , foldMany
384+ , concatMapWith
385+ , concatMap
386+ , concatMapM
387+
388+ -- * Repeated Fold
389+ , foldMany -- XXX Rename to foldRepeat
390+
391+ -- * Buffered Operations
392+ -- | Operations that require buffering of the stream.
393+ , reverse
422394
423− -- ** Multi-Stream folds
395+ -- * Multi-Stream folds
424396 -- | Operations that consume multiple streams at the same time.
425397 , eqBy
426398 , cmpBy
core/src/Streamly/Internal/Data/Stream/Eliminate.hs+4−2
@@ -221,8 +221,10 @@ parseK = parse
221221
222222-- | Parse a stream using the supplied 'Parser'.
223223--
224−-- Unlike folds, parsers may not always result in a valid output, they may
225−-- result in an error. For example:
224+-- Parsers (See "Streamly.Internal.Data.Parser") are more powerful folds that
225+-- add backtracking and error functionality to terminating folds. Unlike folds,
226+-- parsers may not always result in a valid output, they may result in an
227+-- error. For example:
226228--
227229-- >>> Stream.parse (Parser.takeEQ 1 Fold.drain) Stream.nil
228230-- *** Exception: ParseError "takeEQ: Expecting exactly 1 elements, input terminated on 0"