on 8a3828a help sign in
streamly/src/Streamly/Prelude.hs
804 lines 28 kB history raw
1{-# OPTIONS_GHC -Wno-orphans #-}
3#include "inline.hs"
5-- |
6-- Module : Streamly.Prelude
7-- Copyright : (c) 2017 Harendra Kumar
8--
9-- License : BSD3
10-- Maintainer : streamly@composewell.com
11-- Stability : experimental
12-- Portability : GHC
13--
14-- This module is designed to be imported qualified:
15--
16-- @
17-- import qualified Streamly.Prelude as S
18-- @
19--
20-- Functions with the suffix @M@ are general functions that work on monadic
21-- arguments. The corresponding functions without the suffix @M@ work on pure
22-- arguments and can in general be derived from their monadic versions but are
23-- provided for convenience and for consistency with other pure APIs in the
24-- @base@ package.
25--
26-- In many cases, short definitions of the combinators are provided in the
27-- documentation for illustration. The actual implementation may differ for
28-- performance reasons.
29--
30-- Functions having a 'MonadAsync' constraint work concurrently when used with
31-- appropriate stream type combinator. Please be careful to not use 'parallely'
32-- with infinite streams.
33--
34-- Deconstruction and folds accept a 'SerialT' type instead of a polymorphic
35-- type to ensure that streams always have a concrete monomorphic type by
36-- default, reducing type errors. In case you want to use any other type of
37-- stream you can use one of the type combinators provided in the "Streamly"
38-- module to convert the stream type.
40module Streamly.Prelude
41 (
42 -- * Construction
43 -- ** Primitives
44 -- | Primitives to construct a stream from pure values or monadic actions.
45 -- All other stream construction and generation combinators described later
46 -- can be expressed in terms of these primitives. However, the special
47 -- versions provided in this module can be much more efficient in most
48 -- cases. Users can create custom combinators using these primitives.
50 nil
51 , cons
52 , (.:)
54 , consM
55 , (|:)
57 -- ** From Values
58 -- | Generate a monadic stream from a seed value or values.
59 , yield
60 , yieldM
61 , repeat
62 , repeatM
63 , replicate
64 , replicateM
66 -- Note: Using enumeration functions e.g. 'Prelude.enumFromThen' turns out
67 -- to be slightly faster than the idioms like @[from, then..]@.
68 --
69 -- ** Enumeration
70 -- | We can use the 'Enum' type class to enumerate a type producing a list
71 -- and then convert it to a stream:
72 --
73 -- @
74 -- 'fromList' $ 'Prelude.enumFromThen' from then
75 -- @
76 --
77 -- However, this is not particularly efficient.
78 -- The 'Enumerable' type class provides corresponding functions that
79 -- generate a stream instead of a list, efficiently.
81 , Enumerable (..)
82 , enumerate
83 , enumerateTo
85 -- ** From Generators
86 -- | Generate a monadic stream from a seed value and a generator function.
87 , unfoldr
88 , unfoldrM
89 , unfold
90 , iterate
91 , iterateM
92 , fromIndices
93 , fromIndicesM
95 -- ** From Containers
96 -- | Convert an input structure, container or source into a stream. All of
97 -- these can be expressed in terms of primitives.
98 , fromList
99 , fromListM
100 , fromFoldable
101 , fromFoldableM
103 -- * Elimination
105 -- ** Deconstruction
106 -- | It is easy to express all the folds in terms of the 'uncons' primitive,
107 -- however the specific implementations provided later are generally more
108 -- efficient.
109 --
110 , uncons
111 , tail
112 , init
114 -- ** Folding
115-- | In imperative terms a fold can be considered as a loop over the stream
116-- that reduces the stream to a single value.
117-- Left and right folds both use a fold function @f@ and an identity element
118-- @z@ (@zero@) to deconstruct a recursive data structure and reconstruct a
119-- new data structure. The new structure may be a recursive construction (a
120-- container) or a non-recursive single value reduction of the original
121-- structure.
122--
123-- Both right and left folds are mathematical duals of each other, they are
124-- functionally equivalent. Operationally, a left fold on a left associated
125-- structure behaves exactly in the same way as a right fold on a right
126-- associated structure. Similarly, a left fold on a right associated structure
127-- behaves in the same way as a right fold on a left associated structure.
128-- However, the behavior of a right fold on a right associated structure is
129-- operationally different (even though functionally equivalent) than a left
130-- fold on the same structure.
131--
132-- On right associated structures like Haskell @cons@ lists or Streamly
133-- streams, a lazy right fold is naturally suitable for lazy recursive
134-- reconstruction of a new structure, while a strict left fold is naturally
135-- suitable for efficient reduction. In right folds control is in the hand of
136-- the @puller@ whereas in left folds the control is in the hand of the
137-- @pusher@.
138--
139-- The behavior of right and left folds are described in detail in the
140-- individual fold's documentation. To illustrate the two folds for right
141-- associated @cons@ lists:
142--
143-- > foldr :: (a -> b -> b) -> b -> [a] -> b
144-- > foldr f z [] = z
145-- > foldr f z (x:xs) = x `f` foldr f z xs
146-- >
147-- > foldl :: (b -> a -> b) -> b -> [a] -> b
148-- > foldl f z [] = z
149-- > foldl f z (x:xs) = foldl f (z `f` x) xs
150--
151-- @foldr@ is conceptually equivalent to:
152--
153-- > foldr f z [] = z
154-- > foldr f z [x] = f x z
155-- > foldr f z xs = foldr f (foldr f z (tail xs)) [head xs]
156--
157-- @foldl@ is conceptually equivalent to:
158--
159-- > foldl f z [] = z
160-- > foldl f z [x] = f z x
161-- > foldl f z xs = foldl f (foldl f z (init xs)) [last xs]
162--
163-- Left and right folds are duals of each other.
164--
165-- @
166-- foldr f z xs = foldl (flip f) z (reverse xs)
167-- foldl f z xs = foldr (flip f) z (reverse xs)
168-- @
169--
170-- More generally:
171--
172-- @
173-- foldr f z xs = foldl g id xs z where g k x = k . f x
174-- foldl f z xs = foldr g id xs z where g x k = k . flip f x
175-- @
176--
178-- As a general rule, foldr cannot have state and foldl cannot have control.
180-- NOTE: Folds are inherently serial as each step needs to use the result of
181-- the previous step. However, it is possible to fold parts of the stream in
182-- parallel and then combine the results using a monoid.
184 -- ** Right Folds
185 -- $rightfolds
186 , foldrM
187 , foldr
189 -- ** Left Folds
190 -- $leftfolds
191 , foldl'
192 , foldl1'
193 , foldlM'
195 -- ** Composable Left Folds
196 -- $runningfolds
198 , fold
200 -- ** Full Folds
201 -- | Folds that are guaranteed to evaluate the whole stream.
203 -- -- ** To Summary (Full Folds)
204 -- -- | Folds that summarize the stream to a single value.
205 , drain
206 , last
207 , length
208 , sum
209 , product
211 -- -- ** To Summary (Maybe) (Full Folds)
212 -- -- | Folds that summarize a non-empty stream to a 'Just' value and return
213 -- 'Nothing' for an empty stream.
214 , maximumBy
215 , maximum
216 , minimumBy
217 , minimum
218 , the
220 -- ** Lazy Folds
221 --
222 -- | Folds that generate a lazy structure. Note that the generated
223 -- structure may not be lazy if the underlying monad is strict.
225 -- -- ** To Containers (Full Folds)
226 -- -- | Convert or divert a stream into an output structure, container or
227 -- sink.
228 , toList
230 -- ** Partial Folds
231 -- | Folds that may terminate before evaluating the whole stream. These
232 -- folds strictly evaluate the stream until the result is determined.
234 -- -- ** To Elements (Partial Folds)
235 , drainN
236 , drainWhile
238 -- -- | Folds that extract selected elements of a stream or their properties.
239 , (!!)
240 , head
241 , findM
242 , find
243 , lookup
244 , findIndex
245 , elemIndex
247 -- -- ** To Boolean (Partial Folds)
248 -- -- | Folds that summarize the stream to a boolean value.
249 , null
250 , elem
251 , notElem
252 , all
253 , any
254 , and
255 , or
257 -- ** Multi-Stream folds
258 , eqBy
259 , cmpBy
260 , isPrefixOf
261 , isSubsequenceOf
263 -- trimming sequences
264 , stripPrefix
266 -- * Transformation
268 -- ** Mapping
269 -- | In imperative terms a map operation can be considered as a loop over
270 -- the stream that transforms the stream into another stream by performing
271 -- an operation on each element of the stream.
272 --
273 -- 'map' is the least powerful transformation operation with strictest
274 -- guarantees. A map, (1) is a stateless loop which means that no state is
275 -- allowed to be carried from one iteration to another, therefore,
276 -- operations on different elements are guaranteed to not affect each
277 -- other, (2) is a strictly one-to-one transformation of stream elements
278 -- which means it guarantees that no elements can be added or removed from
279 -- the stream, it can merely transform them.
280 , map
281 , sequence
282 , mapM
284 -- ** Special Maps
285 , mapM_
286 , trace
287 , tap
289 -- ** Scanning
290 --
291 -- | A scan is more powerful than map. While a 'map' is a stateless loop, a
292 -- @scan@ is a stateful loop which means that a state can be shared across
293 -- all the loop iterations, therefore, future iterations can be impacted by
294 -- the state changes made by the past iterations. A scan yields the state
295 -- of the loop after each iteration. Like a map, a @postscan@ or @prescan@
296 -- does not add or remove elements in the stream, it just transforms them.
297 -- However, a @scan@ adds one extra element to the stream.
298 --
299 -- A left associative scan, also known as a prefix sum, can be thought of
300 -- as a stream transformation consisting of left folds of all prefixes of a
301 -- stream. Another way of thinking about it is that it streams all the
302 -- intermediate values of the accumulator while applying a left fold on the
303 -- input stream. A right associative scan, on the other hand, can be
304 -- thought of as a stream consisting of right folds of all the suffixes of
305 -- a stream.
306 --
307 -- The following equations hold for lists:
308 --
309 -- > scanl f z xs == map (foldl f z) $ inits xs
310 -- > scanr f z xs == map (foldr f z) $ tails xs
311 --
312 -- @
313 -- > scanl (+) 0 [1,2,3,4]
314 -- 0 = 0
315 -- 0 + 1 = 1
316 -- 0 + 1 + 2 = 3
317 -- 0 + 1 + 2 + 3 = 6
318 -- 0 + 1 + 2 + 3 + 4 = 10
319 --
320 -- > scanr (+) 0 [1,2,3,4]
321 -- 1 + 2 + 3 + 4 + 0 = 10
322 -- 2 + 3 + 4 + 0 = 9
323 -- 3 + 4 + 0 = 7
324 -- 4 + 0 = 4
325 -- 0 = 0
326 -- @
327 --
328 -- Left and right scans are duals:
329 --
330 -- > scanr f z xs == reverse $ scanl (flip f) z (reverse xs)
331 -- > scanl f z xs == reverse $ scanr (flip f) z (reverse xs)
332 --
333 -- A scan is a stateful map i.e. a combination of map and fold:
334 --
335 -- > map f xs = tail $ scanl (\_ x -> f x) z xs
336 -- > map f xs = reverse $ head $ scanr (\_ x -> f x) z xs
337 --
338 -- > foldl f z xs = last $ scanl f z xs
339 -- > foldr f z xs = head $ scanr f z xs
341 -- ** Left scans
342 , scanl'
343 , scanlM'
344 , postscanl'
345 , postscanlM'
346 , scanl1'
347 , scanl1M'
349 -- ** Scan Using Fold
350 , scan
351 , postscan
353 -- ** Filtering
354 -- | Remove some elements from the stream based on a predicate. In
355 -- imperative terms a filter over a stream corresponds to a loop with a
356 -- @continue@ clause for the cases when the predicate fails.
358 , filter
359 , filterM
361 -- ** Mapping Filters
362 -- | Mapping along with filtering
364 , mapMaybe
365 , mapMaybeM
367 -- ** Deleting Elements
368 -- | Deleting elements is a special case of de-interleaving streams.
369 , deleteBy
370 , uniq
372 -- ** Inserting Elements
373 -- | Inserting elements is a special case of interleaving/merging streams.
375 , insertBy
376 , intersperseM
377 , intersperse
379 -- ** Indexing
380 -- | Indexing can be considered as a special type of zipping where we zip a
381 -- stream with an index stream.
382 , indexed
383 , indexedR
385 -- ** Reordering Elements
386 , reverse
388 -- ** Trimming
389 -- | Take or remove elements from one or both ends of a stream.
390 , take
391 , takeWhile
392 , takeWhileM
393 , drop
394 , dropWhile
395 , dropWhileM
397 -- -- ** Breaking
399 , chunksOf
400 , intervalsOf
402 -- ** Searching
403 -- | Finding the presence or location of an element, a sequence of elements
404 -- or another stream within a stream.
406 -- -- ** Searching Elements
407 , findIndices
408 , elemIndices
410 -- ** Splitting
411 -- | In general we can express splitting in terms of parser combinators.
412 -- These are some common use functions for convenience and efficiency.
413 -- While parsers can fail these functions are designed to transform a
414 -- stream without failure with a predefined behavior for all cases.
415 --
416 -- In general, there are three possible ways of combining stream segments
417 -- with a separator. The separator could be prefixed to each segment,
418 -- suffixed to each segment, or it could be infixed between segments.
419 -- 'intersperse' and 'intercalate' operations are examples of infixed
420 -- combining whereas 'unlines' is an example of suffixed combining. When we
421 -- split a stream with separators we can split in three different ways,
422 -- each being an opposite of the three ways of combining.
423 --
424 -- Splitting may keep the separator or drop it. Depending on how we split,
425 -- the separator may be kept attached to the stream segments in prefix or
426 -- suffix position or as a separate element in infix position. Combinators
427 -- like 'splitOn' that use @On@ in their names drop the separator and
428 -- combinators that use 'With' in their names keep the separator. When a
429 -- segment is missing it is considered as empty, therefore, we never
430 -- encounter an error in parsing.
432 -- -- ** Splitting By Elements
433 , splitOn
434 , splitOnSuffix
436 , splitWithSuffix
437 , wordsBy -- strip, compact and split
439 -- ** Grouping
440 -- | Splitting a stream by combining multiple contiguous elements into
441 -- groups using some criterion.
442 , groups
443 , groupsBy
444 , groupsByRolling
446 -- * Combining Streams
447 -- | New streams can be constructed by appending, merging or zipping
448 -- existing streams.
450 -- ** Appending
451 -- | Streams form a 'Semigroup' and a 'Monoid' under the append
452 -- operation. Appending can be considered as a generalization of the `cons`
453 -- operation to consing a stream to a stream.
454 --
455 -- @
456 --
457 -- -------Stream m a------|-------Stream m a------|=>----Stream m a---
458 --
459 -- @
460 --
461 -- @
462 -- >> S.toList $ S.fromList [1,2] \<> S.fromList [3,4]
463 -- [1,2,3,4]
464 -- >> S.toList $ fold $ [S.fromList [1,2], S.fromList [3,4]]
465 -- [1,2,3,4]
466 -- @
468 -- ** Merging
469 -- | Streams form a commutative semigroup under the merge
470 -- operation. Merging can be considered as a generalization of inserting an
471 -- element in a stream to interleaving a stream with another stream.
472 --
473 -- @
474 --
475 -- -------Stream m a------|
476 -- |=>----Stream m a---
477 -- -------Stream m a------|
478 -- @
479 --
481 -- , merge
482 , mergeBy
483 , mergeByM
484 , mergeAsyncBy
485 , mergeAsyncByM
487 -- ** Zipping
488 -- |
489 -- @
490 --
491 -- -------Stream m a------|
492 -- |=>----Stream m c---
493 -- -------Stream m b------|
494 -- @
495 --
496 , zipWith
497 , zipWithM
498 , zipAsyncWith
499 , zipAsyncWithM
501 {-
502 -- ** Folding Containers of Streams
503 -- | These are variants of standard 'Foldable' fold functions that use a
504 -- polymorphic stream sum operation (e.g. 'async' or 'wSerial') to fold a
505 -- finite container of streams. Note that these are just special cases of
506 -- the more general 'concatMapWith' operation.
507 --
508 , foldMapWith
509 , forEachWith
510 , foldWith
511 -}
513 -- ** Folding Streams of Streams
514 -- | Stream operations like map and filter represent loop processing in
515 -- imperative programming terms. Similarly, the imperative concept of
516 -- nested loops are represented by streams of streams. The 'concatMap'
517 -- operation represents nested looping.
518 -- A 'concatMap' operation loops over the input stream and then for each
519 -- element of the input stream generates another stream and then loops over
520 -- that inner stream as well producing effects and generating a single
521 -- output stream.
522 -- The 'Monad' instances of different stream types provide a more
523 -- convenient way of writing nested loops. Note that the monad bind
524 -- operation is just @flip concatMap@.
525 --
526 -- One dimension loops are just a special case of nested loops. For
527 -- example, 'concatMap' can degenerate to a simple map operation:
528 --
529 -- > map f m = S.concatMap (\x -> S.yield (f x)) m
530 --
531 -- Similarly, 'concatMap' can perform filtering by mapping an element to a
532 -- 'nil' stream:
533 --
534 -- > filter p m = S.concatMap (\x -> if p x then S.yield x else S.nil) m
535 --
537 , concatMapWith
538 , concatMap
539 , concatMapM
540 , concatUnfold
542 -- * Exceptions
543 , before
544 , after
545 , bracket
546 , onException
547 , finally
548 , handle
550 -- * Deprecated
551 , once
552 , each
553 , scanx
554 , foldx
555 , foldxM
556 , foldr1
557 , runStream
558 , runN
559 , runWhile
560 , fromHandle
561 , toHandle
562 )
563where
565import Prelude
566 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
567 foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
568 notElem, maximum, minimum, head, last, tail, length, null,
569 reverse, iterate, init, and, or, lookup, foldr1, (!!),
570 scanl, scanl1, repeat, replicate, concatMap, span)
572import Streamly.Internal.Prelude
574-- $rightfolds
575--
576-- Let's take a closer look at the @foldr@ definition for lists, as given
577-- earlier:
578--
579-- @
580-- foldr f z (x:xs) = x \`f` foldr f z xs
581-- @
582--
583-- @foldr@ invokes the fold step function @f@ as @f x (foldr f z xs)@. At each
584-- invocation of @f@, @foldr@ gives us the next element in the input container
585-- @x@ and a recursive expression @foldr f z xs@ representing the yet unbuilt
586-- (lazy thunk) part of the output.
587--
588-- When @f x xs@ is lazy in @xs@ it can consume the input one element at a time
589-- in FIFO order to build a lazy output expression. For example,
590--
591-- > f x remaining = show x : remaining
592--
593-- @take 2 $ foldr f [] (1:2:undefined)@ would consume the input lazily on
594-- demand, consuming only first two elements and resulting in ["1", "2"]. @f@
595-- can terminate recursion by not evaluating the @remaining@ part:
596--
597-- > f 2 remaining = show 2 : []
598-- > f x remaining = show x : remaining
599--
600-- @f@ would terminate recursion whenever it sees element @2@ in the input.
601-- Therefore, @take 2 $ foldr f [] (1:2:undefined)@ would work without any
602-- problem.
603--
604-- On the other hand, if @f a b@ is strict in @b@ it would end up consuming the
605-- whole input right away and expanding the recursive expression @b@ (i.e.
606-- @foldr f z xs@) fully before it yields an output expression, resulting in
607-- the following /right associated expression/:
608--
609-- @
610-- foldr f z xs == x1 \`f` (x2 \`f` ...(xn \`f` z))
611-- @
612--
613-- For example,
614--
615-- > f x remaining = x + remaining
616--
617-- With this definition, @foldr f 0 [1..1000]@, would recurse completely until
618-- it reaches the terminating case @... `f` (1000 `f` 0)@, and then
619-- start reducing the whole expression from right to left, therefore, consuming
620-- the input elements in LIFO order. Thus, such an evaluation would require
621-- memory proportional to the size of input. Try out @foldr (+) 0 (map (\\x ->
622-- trace (show x) x) [1..10])@.
623--
624-- Notice the order of the arguments to the step function @f a b@. It follows
625-- the order of @a@ and @b@ in the right associative recursive expression
626-- generated by expanding @a \`f` b@.
627--
628-- A right fold is a pull fold, the step function is the puller, it can pull
629-- more data from the input container by using its second argument in the
630-- output expression or terminate pulling by not using it. As a corollary:
631--
632-- 1. a step function which is lazy in its second argument (usually functions
633-- or constructors that build a lazy structure e.g. @(:)@) can pull lazily on
634-- demand.
635-- 2. a step function strict in its second argument (usually reducers e.g.
636-- (+)) would end up pulling all of its input and buffer it in memory before
637-- potentially reducing it.
638--
639-- A right fold is suitable for lazy reconstructions e.g. transformation,
640-- mapping, filtering of /right associated input structures/ (e.g. cons lists).
641-- Whereas a left fold is suitable for reductions (e.g. summing a stream of
642-- numbers) of right associated structures. Note that these roles will reverse
643-- for left associated structures (e.g. snoc lists). Most of our observations
644-- here assume right associated structures, lists being the canonical example.
645--
646-- 1. A lazy FIFO style pull using a right fold allows pulling a potentially
647-- /infinite/ input stream lazily, perform transformations on it, and
648-- reconstruct a new structure without having to buffer the whole structure. In
649-- contrast, a left fold would buffer the entire structure before the
650-- reconstructed structure can be consumed.
651-- 2. Even if buffering the entire input structure is ok, we need to keep in
652-- mind that a right fold reconstructs structures in a FIFO style, whereas a
653-- left fold reconstructs in a LIFO style, thereby reversing the order of
654-- elements..
655-- 3. A right fold has termination control and therefore can terminate early
656-- without going through the entire input, a left fold cannot terminate
657-- without consuming all of its input. For example, a right fold
658-- implementation of 'or' can terminate as soon as it finds the first 'True'
659-- element, whereas a left fold would necessarily go through the entire input
660-- irrespective of that.
661-- 4. Reduction (e.g. using (+) on a stream of numbers) using a right fold
662-- occurs in a LIFO style, which means that the entire input gets buffered
663-- before reduction starts. Whereas with a strict left fold reductions occur
664-- incrementally in FIFO style. Therefore, a strict left fold is more suitable
665-- for reductions.
666--
668-- $leftfolds
669--
670-- Note that the observations below about the behavior of a left fold assume
671-- that we are working on a right associated structure like cons lists and
672-- streamly streams. If we are working on a left associated structure (e.g.
673-- snoc lists) the roles of right and left folds would reverse.
674--
675-- Let's take a closer look at the @foldl@ definition for lists given above:
676--
677-- @
678-- foldl f z (x:xs) = foldl f (z \`f` x) xs
679-- @
680--
681-- @foldl@ calls itself recursively, in each call it invokes @f@ as @f z x@
682-- providing it with the result accumulated till now @z@ (the state) and the
683-- next element from the input container. First call to @f@ is supplied with
684-- the initial value of the accumulator @z@ and each subsequent call uses the
685-- output of the previous call to @f z x@.
686--
687-- >> foldl' (+) 0 [1,2,3]
688-- > 6
689--
690-- The recursive call at the head of the output expression is bound to be
691-- evaluated until recursion terminates, therefore, a left fold always
692-- /consumes the whole input container/. The following would result in an
693-- error, even though the fold is not using the values at all:
694--
695-- >> foldl' (\_ _ -> 0) 0 (1:undefined)
696-- > *** Exception: Prelude.undefined
697--
698-- As @foldl@ recurses, it builds the left associated expression shown below.
699-- Notice, the order of the arguments to the step function @f b a@. It follows
700-- the left associative recursive expression generated by expanding @b \`f` a@.
701--
702-- @
703-- foldl f z xs == (((z \`f` x1) \`f` x2) ...) \`f` xn
704-- @
705--
706--
707-- The strict left fold @foldl'@ forces the reduction of its argument @z \`f`
708-- x@ before using it, therefore it never builds the whole expression in
709-- memory. Thus, @z \`f` x1@ would get reduced to @z1@ and then @z1 \`f` x2@
710-- would get reduced to @z2@ and so on, incrementally reducing the expression
711-- from left to right as it recurses, consuming the input in FIFO order. Try
712-- out @foldl' (+) 0 (map (\\x -> trace (show x) x) [1..10])@ to see how it
713-- works. For example:
714--
715-- @
716-- > S.foldl' (+) 0 $ S.fromList [1,2,3,4]
717-- 10
718-- @
719--
720-- @
721-- 0 + 1 = 1
722-- 1 + 2 = 3
723-- 3 + 3 = 6
724-- 6 + 4 = 10
725-- @
726--
727-- However, @foldl'@ evaluates the accumulator only to WHNF. It may further
728-- help if the step function uses a strict data structure as accumulator to
729-- improve performance and to keep the expression fully reduced at all times
730-- during the fold.
731--
732-- A left fold can also build a new structure instead of reducing one if a
733-- constructor is used as a fold step. However, it may not be very useful
734-- because it will consume the whole input and construct the new structure in
735-- memory before we can consume it. Thus the whole structure gets buffered in
736-- memory. When the list constructor is used it would build a new list in
737-- reverse (LIFO) order:
738--
739-- @
740-- > S.foldl' (flip (:)) [] $ S.fromList [1,2,3,4]
741-- [4,3,2,1]
742-- @
743--
744-- A left fold is a push fold. The producer pushes its contents to the step
745-- function of the fold. The step function therefore has no control to stop the
746-- input, it can only discard it if it does not need it. We can also consider a
747-- left fold as a state machine where the state is store in the accumulator,
748-- the state can be modified based on new inputs that are pushed to the fold.
749--
750-- In general, a strict left fold is a reducing fold, whereas a right fold is a
751-- constructing fold. A strict left fold reduces in a FIFO order whereas it
752-- constructs in a LIFO order, and vice-versa for the right fold. See the
753-- documentation of 'foldrM' for a discussion on where a left or right fold is
754-- suitable.
755--
756-- To perform a left fold lazily without having to consume all the input one
757-- can use @scanl@ to stream the intermediate results of the fold and consume
758-- the resulting stream lazily.
759--
761-- $runningfolds
762--
763-- "Streamly.Data.Fold" module defines composable left folds which can be combined
764-- together in many interesting ways. Those folds can be run using 'fold'.
765-- The following two ways of folding are equivalent in functionality and
766-- performance,
767--
768-- >>> S.fold FL.sum (S.enumerateFromTo 1 100)
769-- 5050
770-- >>> S.sum (S.enumerateFromTo 1 100)
771-- 5050
772--
773-- However, left folds cannot terminate early even if it does not need to
774-- consume more input to determine the result. Therefore, the performance is
775-- equivalent only for full folds like 'sum' and 'length'. For partial folds
776-- like 'head' or 'any' the the folds defined in this module may be much more
777-- efficient because they are implemented as right folds that terminate as soon
778-- as we get the result. Note that when a full fold is composed with a partial
779-- fold in parallel the performance is not impacted as we anyway have to
780-- consume the whole stream due to the full fold.
781--
782-- >>> S.head (1 `S.cons` undefined)
783-- Just 1
784-- >>> S.fold FL.head (1 `S.cons` undefined)
785-- *** Exception: Prelude.undefined
786--
787-- However, we can wrap the fold in a scan to convert it into a lazy stream of
788-- fold steps. We can then terminate the stream whenever we want. For example,
789--
790-- >>> S.toList $ S.take 1 $ S.scan FL.head (1 `S.cons` undefined)
791-- [Nothing]
792--
793-- The following example extracts the input stream up to a point where the
794-- running average of elements is no more than 10:
795--
796-- @
797-- > S.toList
798-- $ S.map (fromJust . fst)
799-- $ S.takeWhile (\\(_,x) -> x <= 10)
800-- $ S.postscan ((,) \<$> FL.last \<*> avg) (S.enumerateFromTo 1.0 100.0)
801-- @
802-- @
803-- [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0]
804-- @