@@ -6,61 +6,55 @@
66-- Stability : experimental
77-- Portability : GHC
88--
9−-- 'Fold' type represents an effectful action that consumes a value from an
10−-- input stream and combines it with a single final value often called an
11−-- accumulator, returning the resulting output accumulator. Values from a
12−-- stream can be /pushed/ to the fold and consumed one at a time. It can also
13−-- be called a consumer of stream or a sink. It is a data representation of
14−-- the standard 'Streamly.Prelude.foldl'' function. A 'Fold' can be turned
15−-- into an effect (@m b@) using 'Streamly.Prelude.fold' by supplying it the
16−-- input stream.
9+-- The 'Fold' type represents an effectful action that absorbs a value into an
10+-- accumulator. For example, a 'sum' 'Fold' represents adding the input to the
11+-- accumulated sum. A fold driver e.g. 'Streamly.Prelude.fold' pushes values
12+-- from a stream to the 'Fold' one at a time, reducing the stream to a single
13+-- value. Therefore, a fold can also be thought of as a sink or a stream
14+-- consumer.
1715--
18−-- Using this representation multiple folds can be combined efficiently using
19−-- combinators; a stream can then be supplied to the combined fold and it would
20−-- distribute the input to constituent folds according to the composition. For
21−-- example, an applicative composition distributes the same input to the
22−-- constituent folds and then combines the resulting fold outputs. Similarly,
23−-- a partitioning combinator divides the input among constituent folds.
16+-- A 'Fold' is in fact a data representation of a standard left fold ('foldl').
17+-- Unlike the standard left folds, 'Fold's can terminate at any point e.g. the
18+-- 'head' fold would terminate immediately after returning the head element.
2419--
25−-- = Monoids
20+-- 'Fold's can be combined efficiently using combinators provided in this
21+-- module; a stream supplied to the combined fold is provided to the
22+-- constituent folds according to the behavior of the combinator. For example,
23+-- the 'tee' combinator distributes the input stream to two folds and then
24+-- combines the resulting fold outputs. Similarly, a 'partition' combinator
25+-- divides the input among constituent folds.
2626--
27−-- Monoids allow modular folding in general. Most of the folds in this module
28−-- can be expressed using 'mconcat' and a suitable 'Monoid'. Instead of writing
29−-- folds we can write Monoids instead and turn them into folds.
27+-- = Accumulators and Terminating Folds
3028--
31−-- = Performance Notes
29+-- Folds in this module can be classified in two categories viz. accumulators
30+-- and terminating folds. Accumulators do not have a terminating condition,
31+-- they run forever and consume the entire stream, for example the 'length'
32+-- fold. Terminating folds have a terminating condition and can terminate
33+-- without consuming the entire stream, for example, the 'head' fold.
3234--
33−-- 'Fold' representation is more efficient than using streams when splitting
34−-- streams. @Fold m a b@ can be considered roughly equivalent to a fold action
35−-- @m b -> t m a -> m b@ (where @t@ is a stream type and @m@ is a 'Monad').
36−-- Instead of using a 'Fold' type one could just use a fold action of the shape
37−-- @m b -> t m a -> m b@ for folding streams. However, multiple such actions
38−-- cannot be composed into a single fold function in an efficient manner.
39−-- Using the 'Fold' type we can efficiently split the stream across mutliple
40−-- folds because it allows the compiler to perform stream fusion optimizations.
35+-- = Monoids
4136--
42−-- On the other hand, transformation operations (e.g. 'Streamly.Prelude.map')
43−-- on stream types can be as efficient as transformations on 'Fold' (e.g.
44−-- 'Streamly.Internal.Data.Fold.lmap').
37+-- Monoids allow generalized, modular folding. The accumulators in this module
38+-- can be expressed using 'mconcat' and a suitable 'Monoid'. Instead of
39+-- writing folds we can write Monoids and turn them into folds.
4540--
46−-- = Left folds vs Right Folds
41+-- = Performance Notes
4742--
48−-- The folds in this module are left folds, therefore, even partial folds, e.g.
49−-- @head@ in this module, would drain the whole stream. On the other hand, the
50−-- partial folds in "Streamly.Prelude" module are lazy right folds and would
51−-- terminate as soon as the result is determined. However, the folds in this
52−-- module can be composed but the folds in "Streamly.Prelude" cannot be
53−-- composed.
43+-- 'Streamly.Prelude' module provides fold functions to directly fold streams
44+-- e.g. Streamly.Prelude/'Streamly.Prelude.sum' serves the same purpose as
45+-- Fold/'sum'. However, the functions in Streamly.Prelude cannot be
46+-- efficiently combined together e.g. we cannot drive the input stream through
47+-- @sum@ and @length@ fold functions simultaneously. Using the 'Fold' type we
48+-- can efficiently split the stream across mutliple folds because it allows the
49+-- compiler to perform stream fusion optimizations.
5450--
5551-- = Programmer Notes
5652--
57−-- > import qualified Streamly.Data.Fold as FL
53+-- > import qualified Streamly.Data.Fold as Fold
5854--
5955-- More, not yet exposed, fold combinators can be found in
6056-- "Streamly.Internal.Data.Fold".
6157
62−-- IMPORTANT: keep the signatures consistent with the folds in Streamly.Prelude
63−
6458module Streamly.Data.Fold
6559 (
6660 -- * Fold Type
@@ -73,10 +67,13 @@ module Streamly.Data.Fold
7367
7468 Fold -- (..)
7569
76− -- , tail
77− -- , init
70+ -- * Accumulators
71+ -- ** Monoids
72+ , mconcat
73+ , foldMap
74+ , foldMapM
7875
79− -- ** Full Folds
76+ -- ** Reducers
8077 , drain
8178 , drainBy
8279 , last
@@ -87,24 +84,18 @@ module Streamly.Data.Fold
8784 , maximum
8885 , minimumBy
8986 , minimum
90− -- , the
9187 , mean
9288 , variance
9389 , stdDev
9490
95− -- ** Full Folds (Monoidal)
96− , mconcat
97− , foldMap
98− , foldMapM
99−
100− -- ** Full Folds (To Containers)
91+ -- ** Collectors
10192 -- | Avoid using these folds in scalable or performance critical
10293 -- applications, they buffer all the input in GC memory which can be
10394 -- detrimental to performance if the input is large.
10495
10596 , toList
10697
107− -- ** Partial Folds
98+ -- * Terminating Folds
10899 -- , drainN
109100 -- , drainWhile
110101 -- , lastN
@@ -120,13 +111,12 @@ module Streamly.Data.Fold
120111 , null
121112 , elem
122113 , notElem
123− -- XXX these are slower than right folds even when full input is used
124114 , all
125115 , any
126116 , and
127117 , or
128118
129− -- * Transformations
119+ -- * Output Transformations
130120 -- | Unlike stream producer types (e.g. @SerialT m a@) which have only
131121 -- output side, folds have an input side as well as an output side. In the
132122 -- type @Fold m a b@, the input type is @a@ and the output type is @b@.
@@ -136,19 +126,21 @@ module Streamly.Data.Fold
136126 -- >>> S.fold (fmap show FL.sum) (S.enumerateFromTo 1 100)
137127 -- "5050"
138128 --
139− -- However, the input side or contravariant transformations are more
140− -- interesting for folds. The following sections describe the input
141− -- transformation operations on a fold. The names of the operations are
142− -- consistent with their covariant counterparts in "Streamly.Prelude", the
143− -- only difference is that they are prefixed with 'l' which stands for
144− -- 'left' assuming left side is the input side, notice that in @Fold m a b@
145− -- the type variable @a@ is on the left side.
146−
147− -- ** Covariant Operations
129+ -- Note: Output transformations are also known as covariant
130+ -- transformations.
148131 , sequence
149132 , mapM
150133
151134 {-
135+ -- * Input Transformations
136+ -- The input side transformations are more interesting for folds. The
137+ -- following sections describe the input transformation operations on a
138+ -- fold. The names and signatures of the operations are consistent with
139+ -- corresponding operations in "Streamly.Prelude".
140+ --
141+ -- Note: Input transformations are also known as contravariant
142+ -- transformations.
143+
152144 -- ** Mapping
153145 --, transform
154146 -- , lmap
@@ -180,12 +172,9 @@ module Streamly.Data.Fold
180172 -}
181173
182174 {-
183− -- * Parsing
184175 -- ** Trimming
185176 , ltake
186− -- , lrunFor -- time
187− , ltakeWhile
188− , ltakeWhileM
177+ -- takeByTime
189178 , ldrop
190179 , ldropWhile
191180 , ldropWhileM
@@ -258,7 +247,7 @@ module Streamly.Data.Fold
258247 -- , unzipWith
259248 -- , unzipWithM
260249
261− -- -- * Nested Folds
250+ -- -- * Nesting
262251 -- , concatMap
263252 -- , chunksOf
264253 -- , duplicate -- experimental