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