fold package:base

Given a structure with elements whose type is a Monoid, combine them via the monoid's (<>) operator. This fold is right-associative and lazy in the accumulator. When you need a strict left-associative fold, use foldMap' instead, with id as the map.

Examples

Basic usage:
>>> fold [[1, 2, 3], [4, 5], [6], []]
[1,2,3,4,5,6]
>>> fold $ Node (Leaf (Sum 1)) (Sum 3) (Leaf (Sum 5))
Sum {getSum = 9}
Folds of unbounded structures do not terminate when the monoid's (<>) operator is strict:
>>> fold (repeat Nothing)
* Hangs forever *
Lazy corecursive folds of unbounded structures are fine:
>>> take 12 $ fold $ map (\i -> [i..i+2]) [0..]
[0,1,2,1,2,3,2,3,4,3,4,5]

>>> sum $ take 4000000 $ fold $ map (\i -> [i..i+2]) [0..]
2666668666666
Map each element of the structure into a monoid, and combine the results with (<>). This fold is right-associative and lazy in the accumulator. For strict left-associative folds consider foldMap' instead.

Examples

Basic usage:
>>> foldMap Sum [1, 3, 5]
Sum {getSum = 9}
>>> foldMap Product [1, 3, 5]
Product {getProduct = 15}
>>> foldMap (replicate 3) [1, 2, 3]
[1,1,1,2,2,2,3,3,3]
When a Monoid's (<>) is lazy in its second argument, foldMap can return a result even from an unbounded structure. For example, lazy accumulation enables Data.ByteString.Builder to efficiently serialise large data structures and produce the output incrementally:
>>> import qualified Data.ByteString.Lazy as L

>>> import qualified Data.ByteString.Builder as B

>>> let bld :: Int -> B.Builder; bld i = B.intDec i <> B.word8 0x20

>>> let lbs = B.toLazyByteString $ foldMap bld [0..]

>>> L.take 64 lbs
"0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24"
Left-associative fold of a structure, lazy in the accumulator. This is rarely what you want, but can work well for structures with efficient right-to-left sequencing and an operator that is lazy in its left argument. In the case of lists, foldl, when applied to a binary operator, a starting value (typically the left-identity of the operator), and a list, reduces the list using the binary operator, from left to right:
foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xn
Note that to produce the outermost application of the operator the entire input list must be traversed. Like all left-associative folds, foldl will diverge if given an infinite list. If you want an efficient strict left-fold, you probably want to use foldl' instead of foldl. The reason for this is that the latter does not force the inner results (e.g. z `f` x1 in the above example) before applying them to the operator (e.g. to (`f` x2)). This results in a thunk chain O(n) elements long, which then must be evaluated from the outside-in. For a general Foldable structure this should be semantically identical to:
foldl f z = foldl f z . toList

Examples

The first example is a strict fold, which in practice is best performed with foldl'.
>>> foldl (+) 42 [1,2,3,4]
52
Though the result below is lazy, the input is reversed before prepending it to the initial accumulator, so corecursion begins only after traversing the entire input string.
>>> foldl (\acc c -> c : acc) "abcd" "efgh"
"hgfeabcd"
A left fold of a structure that is infinite on the right cannot terminate, even when for any finite input the fold just returns the initial accumulator:
>>> foldl (\a _ -> a) 0 $ repeat 1
* Hangs forever *
WARNING: When it comes to lists, you always want to use either foldl' or foldr instead.
Left-associative fold of a structure but with strict application of the operator. This ensures that each step of the fold is forced to Weak Head Normal Form before being applied, avoiding the collection of thunks that would otherwise occur. This is often what you want to strictly reduce a finite structure to a single strict result (e.g. sum). For a general Foldable structure this should be semantically identical to,
foldl' f z = foldl' f z . toList
A variant of foldl that has no base case, and thus may only be applied to non-empty structures. This function is non-total and will raise a runtime exception if the structure happens to be empty.
foldl1 f = foldl1 f . toList

Examples

Basic usage:
>>> foldl1 (+) [1..4]
10
>>> foldl1 (+) []
*** Exception: Prelude.foldl1: empty list
>>> foldl1 (+) Nothing
*** Exception: foldl1: empty structure
>>> foldl1 (-) [1..4]
-8
>>> foldl1 (&&) [True, False, True, True]
False
>>> foldl1 (||) [False, False, True, True]
True
>>> foldl1 (+) [1..]
* Hangs forever *
Right-associative fold of a structure, lazy in the accumulator. In the case of lists, foldr, when applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:
foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)
Note that since the head of the resulting expression is produced by an application of the operator to the first element of the list, given an operator lazy in its right argument, foldr can produce a terminating expression from an unbounded list. For a general Foldable structure this should be semantically identical to,
foldr f z = foldr f z . toList

Examples

Basic usage:
>>> foldr (||) False [False, True, False]
True
>>> foldr (||) False []
False
>>> foldr (\c acc -> acc ++ [c]) "foo" ['a', 'b', 'c', 'd']
"foodcba"
Infinite structures
⚠️ Applying foldr to infinite structures usually doesn't terminate. It may still terminate under one of the following conditions:
  • the folding function is short-circuiting
  • the folding function is lazy on its second argument
Short-circuiting
(||) short-circuits on True values, so the following terminates because there is a True value finitely far from the left side:
>>> foldr (||) False (True : repeat False)
True
But the following doesn't terminate:
>>> foldr (||) False (repeat False ++ [True])
* Hangs forever *
Laziness in the second argument
Applying foldr to infinite structures terminates when the operator is lazy in its second argument (the initial accumulator is never used in this case, and so could be left undefined, but [] is more clear):
>>> take 5 $ foldr (\i acc -> i : fmap (+3) acc) [] (repeat 1)
[1,4,7,10,13]
A variant of foldr that has no base case, and thus may only be applied to non-empty structures. This function is non-total and will raise a runtime exception if the structure happens to be empty.

Examples

Basic usage:
>>> foldr1 (+) [1..4]
10
>>> foldr1 (+) []
Exception: Prelude.foldr1: empty list
>>> foldr1 (+) Nothing
*** Exception: foldr1: empty structure
>>> foldr1 (-) [1..4]
-2
>>> foldr1 (&&) [True, False, True, True]
False
>>> foldr1 (||) [False, False, True, True]
True
>>> foldr1 (+) [1..]
* Hangs forever *
A strict version of foldl1.
The foldM function is analogous to foldl, except that its result is encapsulated in a monad. Note that foldM works from left-to-right over the list arguments. This could be an issue where (>>) and the `folded function' are not commutative.
foldM f a1 [x1, x2, ..., xm]

==

do
a2 <- f a1 x1
a3 <- f a2 x2
...
f am xm
If right-to-left evaluation is required, the input list should be reversed. Note: foldM is the same as foldlM
Like foldM, but discards the result.
A left-associative variant of foldMap that is strict in the accumulator. Use this method for strict reduction when partial results are merged via (<>).

Examples

Define a Monoid over finite bit strings under xor. Use it to strictly compute the xor of a list of Int values.
>>> :set -XGeneralizedNewtypeDeriving

>>> import Data.Bits (Bits, FiniteBits, xor, zeroBits)

>>> import Data.Foldable (foldMap')

>>> import Numeric (showHex)

>>> 

>>> newtype X a = X a deriving (Eq, Bounded, Enum, Bits, FiniteBits)

>>> instance Bits a => Semigroup (X a) where X a <> X b = X (a `xor` b)

>>> instance Bits a => Monoid    (X a) where mempty     = X zeroBits

>>> 

>>> let bits :: [Int]; bits = [0xcafe, 0xfeed, 0xdeaf, 0xbeef, 0x5411]

>>> (\ (X a) -> showString "0x" . showHex a $ "") $ foldMap' X bits
"0x42"
Left-to-right monadic fold over the elements of a structure. Given a structure t with elements (a, b, ..., w, x, y), the result of a fold with an operator function f is equivalent to:
foldlM f z t = do
aa <- f z a
bb <- f aa b
...
xx <- f ww x
yy <- f xx y
return yy -- Just @return z@ when the structure is empty
For a Monad m, given two functions f1 :: a -> m b and f2 :: b -> m c, their Kleisli composition (f1 >=> f2) :: a -> m c is defined by:
(f1 >=> f2) a = f1 a >>= f2
Another way of thinking about foldlM is that it amounts to an application to z of a Kleisli composition:
foldlM f z t =
flip f a >=> flip f b >=> ... >=> flip f x >=> flip f y $ z
The monadic effects of foldlM are sequenced from left to right. If at some step the bind operator (>>=) short-circuits (as with, e.g., mzero in a MonadPlus), the evaluated effects will be from an initial segment of the element sequence. If you want to evaluate the monadic effects in right-to-left order, or perhaps be able to short-circuit after processing a tail of the sequence of elements, you'll need to use foldrM instead. If the monadic effects don't short-circuit, the outermost application of f is to the rightmost element y, so that, ignoring effects, the result looks like a left fold:
((((z `f` a) `f` b) ... `f` w) `f` x) `f` y

Examples

Basic usage:
>>> let f a e = do { print e ; return $ e : a }

>>> foldlM f [] [0..3]
0
1
2
3
[3,2,1,0]
foldr' is a variant of foldr that performs strict reduction from right to left, i.e. starting with the right-most element. The input structure must be finite, otherwise foldr' runs out of space (diverges). If you want a strict right fold in constant space, you need a structure that supports faster than O(n) access to the right-most element, such as Seq from the containers package. This method does not run in constant space for structures such as lists that don't support efficient right-to-left iteration and so require O(n) space to perform right-to-left reduction. Use of this method with such a structure is a hint that the chosen structure may be a poor fit for the task at hand. If the order in which the elements are combined is not important, use foldl' instead.
Right-to-left monadic fold over the elements of a structure. Given a structure t with elements (a, b, c, ..., x, y), the result of a fold with an operator function f is equivalent to:
foldrM f z t = do
yy <- f y z
xx <- f x yy
...
bb <- f b cc
aa <- f a bb
return aa -- Just @return z@ when the structure is empty
For a Monad m, given two functions f1 :: a -> m b and f2 :: b -> m c, their Kleisli composition (f1 >=> f2) :: a -> m c is defined by:
(f1 >=> f2) a = f1 a >>= f2
Another way of thinking about foldrM is that it amounts to an application to z of a Kleisli composition:
foldrM f z t = f y >=> f x >=> ... >=> f b >=> f a $ z
The monadic effects of foldrM are sequenced from right to left, and e.g. folds of infinite lists will diverge. If at some step the bind operator (>>=) short-circuits (as with, e.g., mzero in a MonadPlus), the evaluated effects will be from a tail of the element sequence. If you want to evaluate the monadic effects in left-to-right order, or perhaps be able to short-circuit after an initial sequence of elements, you'll need to use foldlM instead. If the monadic effects don't short-circuit, the outermost application of f is to the leftmost element a, so that, ignoring effects, the result looks like a right fold:
a `f` (b `f` (c `f` (... (x `f` (y `f` z))))).

Examples

Basic usage:
>>> let f i acc = do { print i ; return $ i : acc }

>>> foldrM f [] [0..3]
3
2
1
0
[0,1,2,3]
Given a structure with elements whose type is a Semigroup, combine them via the semigroup's (<>) operator. This fold is right-associative and lazy in the accumulator. When you need a strict left-associative fold, use foldMap1' instead, with id as the map.
Map each element of the structure to a semigroup, and combine the results with (<>). This fold is right-associative and lazy in the accumulator. For strict left-associative folds consider foldMap1' instead.
>>> foldMap1 (:[]) (1 :| [2, 3, 4])
[1,2,3,4]
A left-associative variant of foldMap1 that is strict in the accumulator. Use this for strict reduction when partial results are merged via (<>).
>>> foldMap1' Sum (1 :| [2, 3, 4])
Sum {getSum = 10}
A variant of foldlMap1 where the leftmost element maps to itself.
A variant of foldlMap1' where the leftmost element maps to itself.
Monadic fold over the elements of a non-empty structure, associating to the left, i.e. from left to right.
Left-associative fold of a structure, lazy in the accumulator. This is rarely what you want, but can work well for structures with efficient right-to-left sequencing and an operator that is lazy in its left argument. In case of NonEmpty lists, foldlMap1, when given a function f, a binary operator g, and a list, reduces the list using g from left to right applying f to the leftmost element:
foldlMap1 f g (x1 :| [x2, ..., xn]) == (...(((f x1) `g` x2) `g`...) `g` xn
Note that to produce the outermost application of the operator the entire input list must be traversed. This means that foldlMap1 will diverge if given an infinite list. If you want an efficient strict left-fold, you probably want to use foldlMap1' instead of foldlMap1. The reason for this is that the latter does not force the inner results (e.g. (f x1) `g` x2 in the above example) before applying them to the operator (e.g. to (`g` x3)). This results in a thunk chain <math> elements long, which then must be evaluated from the outside-in. For a general Foldable1 structure this should be semantically identical to:
foldlMap1 f g = foldlMap1 f g . toNonEmpty
Left-associative fold of a structure but with strict application of the operator. This ensures that each step of the fold is forced to Weak Head Normal Form before being applied, avoiding the collection of thunks that would otherwise occur. This is often what you want to strictly reduce a finite structure to a single strict result. For a general Foldable1 structure this should be semantically identical to:
foldlMap1' f z = foldlMap1' f z . toNonEmpty
Map variant of foldlM1.
A variant of foldrMap1 where the rightmost element maps to itself.
A variant of foldrMap1' where the rightmost element maps to itself.