Fold (higherorder function)
In functional programming, fold (also termed reduce, accumulate, aggregate, compress, or inject) refers to a family of higherorder functions that analyze a recursive data structure and through use of a given combining operation, recombine the results of recursively processing its constituent parts, building up a return value. Typically, a fold is presented with a combining function, a top node of a data structure, and possibly some default values to be used under certain conditions. The fold then proceeds to combine elements of the data structure's hierarchy, using the function in a systematic way.
Folds are in a sense dual to unfolds, which take a seed value and apply a function corecursively to decide how to progressively construct a corecursive data structure, whereas a fold recursively breaks that structure down, replacing it with the results of applying a combining function at each node on its terminal values and the recursive results (catamorphism, versus anamorphism of unfolds).
As structural transformations
Folds can be regarded as consistently replacing the structural components of a data structure with functions and values. Lists, for example, are built up in many functional languages from two primitives: any list is either an empty list, commonly called nil ([]
), or is constructed by prefixing an element in front of another list, creating what is called a cons node ( Cons(X1,Cons(X2,Cons(...(Cons(Xn,nil)))))
), resulting from application of a cons
function (written down as a colon (:)
in Haskell). One can view a fold on lists as replacing the nil at the end of the list with a specific value, and replacing each cons with a specific function. These replacements can be viewed as a diagram:
There's another way to perform the structural transformation in a consistent manner, with the order of the two links of each node flipped when fed into the combining function:
These pictures illustrate right and left fold of a list visually. They also highlight the fact that foldr (:) []
is the identity function on lists (a shallow copy in Lisp parlance), as replacing cons with cons
and nil with nil
will not change the result. The left fold diagram suggests an easy way to reverse a list, foldl (flip (:)) []
. Note that the parameters to cons must be flipped, because the element to add is now the right hand parameter of the combining function. Another easy result to see from this vantagepoint is to write the higherorder map function in terms of foldr
, by composing the function to act on the elements with cons
, as:
map f = foldr ((:) . f) []
where the period (.) is an operator denoting function composition.
This way of looking at things provides a simple route to designing foldlike functions on other algebraic data types and structures, like various sorts of trees. One writes a function which recursively replaces the constructors of the datatype with provided functions, and any constant values of the type with provided values. Such a function is generally referred to as a catamorphism.
On lists
The folding of the list [1,2,3,4,5]
with the addition operator would result in 15, the sum of the elements of the list [1,2,3,4,5]
. To a rough approximation, one can think of this fold as replacing the commas in the list with the + operation, giving 1 + 2 + 3 + 4 + 5
.
In the example above, + is an associative operation, so the final result will be the same regardless of parenthesization, although the specific way in which it is calculated will be different. In the general case of nonassociative binary functions, the order in which the elements are combined may influence the final result's value. On lists, there are two obvious ways to carry this out: either by combining the first element with the result of recursively combining the rest (called a right fold), or by combining the result of recursively combining all elements but the last one, with the last element (called a left fold). This corresponds to a binary operator being either rightassociative or leftassociative, in Haskell's or Prolog's terminology. With a right fold, the sum would be parenthesized as 1 + (2 + (3 + (4 + 5)))
, whereas with a left fold it would be parenthesized as (((1 + 2) + 3) + 4) + 5
.
In practice, it is convenient and natural to have an initial value which in the case of a right fold is used when one reaches the end of the list, and in the case of a left fold is what is initially combined with the first element of the list. In the example above, the value 0 (the additive identity) would be chosen as an initial value, giving 1 + (2 + (3 + (4 + (5 + 0))))
for the right fold, and ((((0 + 1) + 2) + 3) + 4) + 5
for the left fold. For multiplication, an initial choice of 0 wouldn't work: 0 * 1 * 2 * 3 * 4 * 5 = 0
. The identity element for multiplication is 1. This would give us the outcome 1 * 1 * 2 * 3 * 4 * 5 = 120 = 5!
.
Linear vs. treelike folds
The use of an initial value is necessary when the combining function f is asymmetrical in its types (e.g. a → b → b
), i.e. when the type of its result is different from the type of the list's elements. Then an initial value must be used, with the same type as that of f 's result, for a linear chain of applications to be possible. Whether it will be left or rightoriented will be determined by the types expected of its arguments by the combining function. If it is the second argument that must be of the same type as the result, then f could be seen as a binary operation that associates on the right, and vice versa.
When the function is a magma, i.e. symmetrical in its types (a → a → a
), and the result type is the same as the list elements' type, the parentheses may be placed in arbitrary fashion thus creating a tree of nested subexpressions, e.g., ((1 + 2) + (3 + 4)) + 5
. If the binary operation f is associative this value will be welldefined, i.e., same for any parenthesization, although the operational details of how it is calculated will be different. This can have significant impact on efficiency if f is nonstrict.
Whereas linear folds are nodeoriented and operate in a consistent manner for each node of a list, treelike folds are wholelist oriented and operate in a consistent manner across groups of nodes.
Special folds for nonempty lists
One often wants to choose the identity element of the operation f as the initial value z. When no initial value seems appropriate, for example, when one wants to fold the function which computes the maximum of its two parameters over a nonempty list to get the maximum element of the list, there are variants of foldr
and foldl
which use the last and first element of the list respectively as the initial value. In Haskell and several other languages, these are called foldr1
and foldl1
, the 1 making reference to the automatic provision of an initial element, and the fact that the lists they are applied to must have at least one element.
These folds use typesymmetrical binary operation: the types of both its arguments, and its result, must be the same. Richard Bird in his 2010 book proposes[1] "a general fold function on nonempty lists" foldrn
which transforms its last element, by applying an additional argument function to it, into a value of the result type before starting the folding itself, and is thus able to use typeasymmetrical binary operation like the regular foldr
to produce a result of type different from the list's elements type.
Implementation
Linear folds
Using Haskell as an example, foldl
and foldr
can be formulated in a few equations.
foldl :: (b > a > b) > b > [a] > b
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
If the list is empty, the result is the initial value. If not, fold the tail of the list using as new initial value the result of applying f to the old initial value and the first element.
foldr :: (a > b > b) > b > [a] > b
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
If the list is empty, the result is the initial value z. If not, apply f to the first element and the result of folding the rest.
Treelike folds
Lists can be folded over in a treelike fashion, both for finite and for indefinitely defined lists:
foldt f z [] = z
foldt f z [x] = f x z
foldt f z xs = foldt f z (pairs f xs)
foldi f z [] = z
foldi f z (x:xs) = f x (foldi f z (pairs f xs))
pairs f (x:y:t) = f x y : pairs f t
pairs _ t = t
In the case of foldi
function, to avoid its runaway evaluation on indefinitely defined lists the function f
must not always demand its second argument's value, at least not all of it, and/or not immediately (see example below).
Folds for nonempty lists
foldl1 f [x] = x
foldl1 f (x:y:xs) = foldl1 f (f x y : xs)
foldr1 f [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)
foldt1 f [x] = x
foldt1 f (x:y:xs) = foldt1 f (f x y : pairs f xs)
foldi1 f [x] = x
foldi1 f (x:xs) = f x (foldi1 f (pairs f xs))
Evaluation order considerations
In the presence of lazy, or nonstrict evaluation, foldr
will immediately return the application of f to the head of the list and the recursive case of folding over the rest of the list. Thus, if f is able to produce some part of its result without reference to the recursive case on its "right" i.e., in its second argument, and the rest of the result is never demanded, then the recursion will stop (e.g., head == foldr (\a b>a) (error "empty list")
). This allows right folds to operate on infinite lists. By contrast, foldl
will immediately call itself with new parameters until it reaches the end of the list. This tail recursion can be efficiently compiled as a loop, but can't deal with infinite lists at all — it will recurse forever in an infinite loop.
Having reached the end of the list, an expression is in effect built by foldl
of nested leftdeepening f
applications, which is then presented to the caller to be evaluated. Were the function f
to refer to its second argument first here, and be able to produce some part of its result without reference to the recursive case (here, on its left i.e., in its first argument), then the recursion would stop. This means that while foldr
recurses on the right, it allows for a lazy combining function to inspect list's elements from the left; and conversely, while foldl
recurses on the left, it allows for a lazy combining function to inspect list's elements from the right, if it so chooses (e.g., last == foldl (\a b>b) (error "empty list")
).
Reversing a list is also tailrecursive (it can be implemented using rev = foldl (\ys x > x : ys) []
). On finite lists, that means that leftfold and reverse can be composed to perform a right fold in a tailrecursive way (cf. 1+>(2+>(3+>0)) == ((0<+3)<+2)<+1
), with a modification to the function f
so it reverses the order of its arguments (i.e., foldr f z == foldl (flip f) z . foldl (flip (:)) []
), tailrecursively building a representation of expression that rightfold would build. The extraneous intermediate list structure can be eliminated with the continuationpassing style technique, foldr f z xs == foldl (\k x> k . f x) id xs z
; similarly, foldl f z xs == foldr (\x k> k . flip f x) id xs z
( flip
is only needed in languages like Haskell with its flipped order of arguments to the combining function of foldl
unlike e.g., in Scheme where the same order of arguments is used for combining functions to both foldl
and foldr
).
Another technical point is that, in the case of left folds using lazy evaluation, the new initial parameter is not being evaluated before the recursive call is made. This can lead to stack overflows when one reaches the end of the list and tries to evaluate the resulting potentially gigantic expression. For this reason, such languages often provide a stricter variant of left folding which forces the evaluation of the initial parameter before making the recursive call. In Haskell this is the foldl'
(note the apostrophe, pronounced 'prime') function in the Data.List
library (one needs to be aware of the fact though that forcing a value built with a lazy data constructor won't force its constituents automatically by itself). Combined with tail recursion, such folds approach the efficiency of loops, ensuring constant space operation, when lazy evaluation of the final result is impossible or undesirable.
Examples
Using a Haskell interpreter, the structural transformations which fold functions perform can be illustrated by constructing a string:
λ> foldr (\x y > concat ["(",x,"+",y,")"]) "0" (map show [1..13])
"(1+(2+(3+(4+(5+(6+(7+(8+(9+(10+(11+(12+(13+0)))))))))))))"
λ> foldl (\x y > concat ["(",x,"+",y,")"]) "0" (map show [1..13])
"(((((((((((((0+1)+2)+3)+4)+5)+6)+7)+8)+9)+10)+11)+12)+13)"
λ> foldt (\x y > concat ["(",x,"+",y,")"]) "0" (map show [1..13])
"(((((1+2)+(3+4))+((5+6)+(7+8)))+(((9+10)+(11+12))+13))+0)"
λ> foldi (\x y > concat ["(",x,"+",y,")"]) "0" (map show [1..13])
"(1+((2+3)+(((4+5)+(6+7))+((((8+9)+(10+11))+(12+13))+0))))"
Infinite treelike folding is demonstrated e.g., in recursive primes production by unbounded sieve of Eratosthenes in Haskell:
primes = 2 : _Y ((3 :) . minus [5,7..] . foldi (\(x:xs) ys > x : union xs ys) []
. map (\p> [p*p, p*p+2*p..]))
_Y g = g (_Y g)  = g . g . g . g . ...
where the function union
operates on ordered lists in a local manner to efficiently produce their set union, and minus
their set difference.
For finite lists, e.g., merge sort (and its duplicatesremoving variety, nubsort
) could be easily defined using treelike folding as
mergesort xs = foldt merge [] [[x]  x < xs]
nubsort xs = foldt union [] [[x]  x < xs]
with the function merge
a duplicatespreserving variant of union
.
Functions head
and last
could have been defined through folding as
head = foldr (\x r > x) (error "head: Empty list")
last = foldl (\a x > x) (error "last: Empty list")
In various languages
Language  Left fold  Right fold  Left fold without initial value  Right fold without initial value  Unfold  Notes  

APL  func⍨/⌽initval,vector  func/vector,initval  func⍨/⌽vector  func/vector  
C# 3.0  ienum 
ienum.Reverse() 
ienum 
ienum.Reverse() 
Aggregate is an extension method ienum is an IEnumerable<T> Similarly in all .NET languages  
C++  std::accumulate( 
std::accumulate( 
in header <numeric> begin, end, rbegin, rend are iterators func can be a function pointer or a function object 

C++17  (init ... op ... pack)  (pack ... op ... init)  (... op pack)  (pack op ...)  op is a binary operator (e.g. +); pack is an unpacked parameter pack; init is an initial value  
CFML  obj.reduce(func,initial)  obj.reduce(func)  Where func receives as arguments the result of the previous operation (or the initial value on the first iteration); the current item; the current item's index or key; and a reference to the obj  
Clojure  (reduce func initval list)  (reduce func initval (reverse list'))  (reduce func list)  (reduce func" (reverse list))  See also clojure.core.reducers/fold  
Common Lisp  (reduce func list :initialvalue initval)  (reduce func list :fromend t :initialvalue initval)  (reduce func list)  (reduce func list :fromend t)  
Curl  {{TreeNode.default treeNode ...} .toIterator} 
{{TreeNode.default treeNode ...} .reverse} 
{for {treeNode 
{for {{treeNode.reverse} 
also DefaultListModel and HashTable implement toIterator  
D  reduce!func(initval, list)  reduce!func(initval, list 
reduce!func(list)  reduce!func( 
in module std.algorithm  
Elm  List.foldl(Fun, Accumulator, List)  List.foldr(Fun, Accumulator, List)  See also List API  
Erlang  lists:foldl(Fun, Accumulator, List)  lists:foldr(Fun, Accumulator, List)  
F#  Seq/List.fold func initval list  List.foldBack func list initval  Seq/List.reduce func list  List.reduceBack func list  Seq.unfold func initval  
Gosu  Iterable.fold(f(agg, e)) 
All are extension methods on Java's Iterable interface, arrays are also supported  
Groovy  list 
list.reverse() 
list 
list.reverse() 

Haskell  foldl func initval list  foldr func initval list  foldl1 func list  foldr1 func list  unfoldr func initval  For foldl, the folding function takes arguments in the opposite order as that for foldr.  
Haxe  Lambda.fold(iterable, func, initval)  
J  verb~/. initval,array  verb/ array,initval  verb~/. array  verb/ array  u/y applies the dyad u between the items of y. "J Dictionary: Insert"  
Java 8+  stream.reduce 
stream.reduce 

JavaScript 1.8 ECMAScript 5 
array.reduce 
array.reduceRight 
array.reduce 
array.reduceRight 

Julia  foldl(op, itr; [init])  foldr(op, itr; [init])  foldl(op, itr)  foldr(op, itr)  
Kotlin  Iterable.fold 
Iterable.foldRight 
Iterable.reduce(func)  Iterable.reduceRight(func)  Other collections also support fold[2] and reduce[3]. There is also Result.fold(onSuccess, onFailure)[4], which reduces a Result<T> (either success or failure) to the return type of onSuccess and onFailure.  
LFE  (lists:foldl func accum list)  (lists:foldr func accum list)  
Logtalk  fold_left(Closure, Initial, List, Result)  fold_right(Closure, Initial, List, Result)  Metapredicates provided by the meta standard library object. The abbreviations foldl and foldr may also be used.  
Maple  foldl(func, initval, sequence)  foldr(func, initval, sequence)  
Mathematica  Fold[func, initval, list]  Fold[func, initval, Reverse[list]]  Fold[func, list]  Fold[func, Reverse[list]]  NestWhileList[func,, initval, predicate]  Fold without an initial value is supported in versions 10.0 and higher. 

MATLAB  fold(@func, list, defaultVal)  fold(@func, flip(list), defaultVal)  fold(@func, list)  fold(@func, flip(list))  Requires Symbolic Math Toolbox, supported from R2016b.  
Maxima  lreduce(func, list, initval)  rreduce(func, list, initval)  lreduce(func, list)  rreduce(func, list)  
Mythryl  fold_left func initval list vector::fold_left func initval vector 
fold_right func initval list vector::fold_right func initval vector 
The supplied function takes its arguments in a tuple.  
OCaml  List.fold_left func initval list Array.fold_left func initval array 
List.fold_right func list initval Array.fold_right func array initval 
Base.Sequence.unfold ~init ~f [5]  
Oz  {FoldL List Func InitVal}  {FoldR List Func InitVal}  
Perl  reduce block initval, list  reduce block list  in List::Util module  
PHP  array_reduce(array, func, initval)  array_reduce( 
array_reduce(array, func)  array_reduce( 
When initval is not supplied, NULL is used, so this is not a true foldl1. Before PHP 5.3, initval can only be integer. "func" is a callback. Try array_reduce online.  
Python 2.x  reduce(func, list, initval)  reduce(lambda x,y: func(y,x), reversed(list), initval)  reduce(func, list)  reduce(lambda x,y: func(y,x), reversed(list))  
Python 3.x  functools.reduce(func, list, initval)  functools.reduce(lambda x,y: func(y,x), reversed(list), initval)  functools.reduce(func, list)  functools.reduce(lambda x,y: func(y,x), reversed(list))  In module functools.[6]  
R  Reduce(func, list, initval)  Reduce(func, list, initval, right=TRUE)  Reduce(func, list)  Reduce(func, list, right=TRUE)  R supports right folding and left or right folding with or without an initial value through the right and init arguments to the Reduce function.  
Ruby  enum enum 
enum.reverse_each enum.reverse_each 
enum enum.reduce(&block) 
enum.reverse_each enum.reverse_each 
In Ruby 1.8.7+, can also pass a symbol representing a function instead of a block. enum is an Enumeration Please notice that these implementations of right folds are wrong for noncommutative &block (also initial value is put on wrong side).  
Rust  iterator.fold(initval, func)  iterator.rev().fold(initval, func)  
Scala  list.foldLeft(initval)(func) (initval /: list)(func) 
list.foldRight(initval)(func) (list :\ initval)(func) 
list.reduceLeft(func)  list.reduceRight(func)  Scala's symbolic fold syntax was intended to resemble the left or rightleaning tree commonly used to explain the fold operation,[7] but has since been reinterpreted as an illustration of a toppling domino.[8] The colon comes from a general Scala syntax mechanism whereby the apparent infix operator is invoked as a method on the left operand with the right operand passed as an argument, or vice versa if the operator's last character is a colon, here applied symmetrically.
Scala also features the treelike folds using the method  
Scheme R^{6}RS  (foldleft func initval list) (vectorfold func initval vector) 
(foldright func initval list) (vectorfoldright func initval vector) 
(reduceleft func defaultval list)  (reduceright func defaultval list)  srfi/1 srfi/43  
Smalltalk  aCollection inject: aValue into: aBlock  aCollection reduce: aBlock  ANSI Smalltalk doesn't define #reduce: but many implementations do.  
Standard ML  foldl func initval list Array.foldl func initval array 
foldr func initval list Array.foldr func initval array 
The supplied function takes its arguments in a tuple. For foldl, the folding function takes arguments in the same order as for foldr.  
Swift  array.reduce(initval, func) reduce(sequence, initval, func) 
array.reverse() 

XPath 3.1  array:foldleft(

array:foldright(

In XPath 3.1 due to historical reasons the array and sequence types are incompatible  thus the need for separate fold functions for array and for sequence
 
Xtend  iterable.fold(initval,[func])  iterable.reduce[func] 
Universality
Fold is a polymorphic function. For any g having a definition
g [] = v
g (x:xs) = f x (g xs)
then g can be expressed as[10]
g = foldr f v
Also, a fixed point combinator can be implemented via fold,[11] proving that iterations can be reduced to folds:
y f = foldr (\_ > f) undefined (repeat undefined)
See also
References
 Richard Bird, "Pearls of Functional Algorithm Design", Cambridge University Press 2010, ISBN 9780521513388, p. 42
 "fold  Kotlin Programming Language". Kotlin. Jetbrains. Retrieved 29 March 2019.
 "reduce  Kotlin Programming Language". Kotlin. Jetbrains. Retrieved 29 March 2019.
 "Result  Kotlin Programming Language". Kotlin. Jetbrains. Retrieved 29 March 2019.
 "Base". Jane Street Capital. Retrieved February 26, 2019.

For reference functools.reduce: import functools
For reference reduce: from functools import reduce  Odersky, Martin (20080105). "Re: Blog: My verdict on the Scala language". Newsgroup: comp.scala.lang. Retrieved 14 October 2013.
 Sterling, Nicholas. "An intuitive feel for Scala's /: operator (foldLeft)". Retrieved 24 June 2016.
 "Fold API  Scala Standard Library". www.scalalang.org. Retrieved 20180410.
 Hutton, Graham. "A tutorial on the universality and expressiveness of fold" (PDF). Journal of Functional Programming (9 (4)): 355–372. Retrieved March 26, 2009.
 Pope, Bernie. "Getting a Fix from the Right Fold" (PDF). The Monad.Reader (6): 5–16. Retrieved May 1, 2011.