2-- Module : Streamly.Data.Fold
3-- Copyright : (c) 2019 Composewell Technologies
5-- Maintainer : harendra@composewell.com
6-- Stability : experimental
9-- A left fold consumes a stream and reduces it to a single value. The fold
10-- operations in "Streamly.Prelude" cannot be combined such that multiple of
11-- them can run on the same stream. This module provides a 'Fold' type that
12-- represents a left fold. Multiple such folds can be combined using
13-- combinators; a stream can then be supplied to the combined fold and it would
14-- distribute the input to constituent folds according to the composition.
15-- For example, an applicative composition distributes the same input to
16-- the constituent folds and then combines the fold outputs. Similarly, a
17-- partitioning combinator can divide the input among constituent folds.
18-- All the combinators in this module are of true streaming nature, stream
19-- elements are not unnecessarily buffered in memory, guaranteeing a constant
22-- Consider this module as the consumer side dual of the "Streamly.Prelude"
23-- module. "Streamly.Prelude" provides combinators that can combine stream
24-- sources in interesting ways whereas this module provides combinators that
25-- combine stream consumers in interesting ways. In other words,
26-- "Streamly.Prelude" provides stream merging capabilities while
27-- "Streamly.Internal.Data.Fold" provides stream splitting capabilities.
29-- > import qualified Streamly.Internal.Data.Fold as FL
31-- Also see the "Streamly.Internal.Data.Sink" module that provides specialized left folds
32-- that discard the outputs.
34-- IMPORTANT: keep the signatures consistent with the folds in Streamly.Prelude
36module Streamly.Data.Fold
40 -- A 'Fold' can be run over a stream using the 'runFold' combinator in
41 -- "Streamly.Prelude":
43 -- >>> S.runFold FL.sum (S.enumerateFromTo 1 100)
67 -- ** Full Folds (Monoidal)
72 -- ** Full Folds (To Containers)
73 -- | Avoid using these folds in scalable or performance critical
74 -- applications, they buffer all the input in GC memory which can be
75 -- detrimental to performance if the input is large.
95 -- XXX these are slower than right folds even when full input is used
102 -- | Unlike stream producer types (e.g. @SerialT m a@) which have only
103 -- output side, folds have an input side as well as an output side. In the
104 -- type @Fold m a b@, the input type is @a@ and the output type is @b@.
105 -- Transformations can be applied either on the input side or on the output
106 -- side. The 'Functor' instance of a fold maps on the output of the fold:
108 -- >>> S.runFold (fmap show FL.sum) (S.enumerateFromTo 1 100)
111 -- However, the input side or contravariant transformations are more
112 -- interesting for folds. The following sections describe the input
113 -- transformation operations on a fold. The names of the operations are
114 -- consistent with their covariant counterparts in "Streamly.Prelude", the
115 -- only difference is that they are prefixed with 'l' which stands for
116 -- 'left' assuming left side is the input side, notice that in @Fold m a b@
117 -- the type variable @a@ is on the left side.
119 -- ** Covariant Operations
136 -- ** Mapping Filters
140 -- ** Scanning Filters
145 -- | Insertion adds more elements to the stream.
168 -- The 'Applicative' instance of a distributing 'Fold' distributes one copy
169 -- of the stream to each fold and combines the results using a function.
173 -- |-------Fold m a b--------|
174 -- ---stream m a---| |---m (b,c,...)
175 -- |-------Fold m a c--------|
180 -- To compute the average of numbers in a stream without going throught he
183 -- >>> let avg = (/) <$> FL.sum <*> fmap fromIntegral FL.length
184 -- >>> S.runFold avg (S.enumerateFromTo 1.0 100.0)
187 -- The 'Semigroup' and 'Monoid' instances of a distributing fold distribute
188 -- the input to both the folds and combines the outputs using Monoid or
189 -- Semigroup instances of the output types:
191 -- >>> import Data.Monoid (Sum)
192 -- >>> S.runFold (FL.head <> FL.last) (fmap Sum $ S.enumerateFromTo 1.0 100.0)
193 -- Just (Sum {getSum = 101.0})
195 -- The 'Num', 'Floating', and 'Fractional' instances work in the same way.
202 -- Direct items in the input stream to different folds using a binary
210 -- | Direct values in the input stream to different folds using an n-ary
219 -- | In an input stream of key value pairs fold values for different keys
220 -- in individual output buckets using the given fold.
227 -- These can be expressed using lmap/lmapM and unzip
234 -- , duplicate -- experimental
239 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
240 foldl, map, mapM_, sequence, all, any, sum, product, elem,
241 notElem, maximum, minimum, head, last, tail, length, null,
242 reverse, iterate, init, and, or, lookup, foldr1, (!!),
243 scanl, scanl1, replicate, concatMap, mconcat, foldMap, unzip,
244 span, splitAt, break, mapM)
246import Streamly.Internal.Data.Fold
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list