{{위키데이터 속성 추적}}
함수형 프로그래밍에서 '''fold'''란 고차 함수의 계열 중 하나이다. reduce, accumulate, compress 혹은 inject 등 다양하게 알려져 있다. 재귀적인 자료 구조를 분석하고, 전달받은 결합된 명령들을 사용하여 재결합하며, 재귀적으로 수행된 그 결과들로 반환 값(return value)을 만들어낸다. 보통 fold는 함수를 자료 구조의 최상위 노드의 조합 함수의 형태로 표현되며, 특정 조건 하에서 사용할 수 있는 어떤 기본 값(default values)을 가질 수 있다. 그리고 계통적인 방식으로 그 함수를 사용하여 자료 구조의 위계 상의 요소들을 조합하는 과정을 진행한다.

== 언어별 비교 ==
{| class="wikitable" style="font-size: 85%"
|-
! scope="col" | 언어
! scope="col" | Left fold
! scope="col" | Right fold
! scope="col" | Left fold (초기값 없음)
! scope="col" | Right fold (초기값 없음)
! scope="col" | Unfold

|- style="vertical-align: top;"
| [[APL|APL]]
| <code>''func''⍨/⌽''initval'',''vector''</code>
| <code>''func''/''vector'',''initval''</code>
| <code>''func''⍨/⌽''vector''</code>
| <code>''func''/''vector''</code>
|

|- style="vertical-align: top;"
| [[C Sharp|C#]] [[C Sharp 3.0|3.0]]
| <code>''ienum''<wbr/>.Aggregate(''initval'', ''func'')</code>
| <code>''ienum''.Reverse()<wbr/>.Aggregate(''initval'', ''func'')</code>
| <code>''ienum''<wbr/>.Aggregate(''func'')</code>
| <code>''ienum''.Reverse()<wbr/>.Aggregate(''func'')</code>
|

|- style="vertical-align: top;"
| [[C++]]
| <code>std::accumulate(<wbr/>''begin'', ''end'', ''initval'', ''func'')</code>
| <code>std::accumulate(<wbr/>''rbegin'', ''rend'', ''initval'', ''func'')</code>
|
|
|

|- style="vertical-align: top;"
| [[C++17]]
| <code>(''initval'' ''op'' ... ''op'' ''pack'')</code>
| <code>(''pack'' ''op'' ... ''op'' ''initval'')</code>
| <code>(... ''op'' ''pack'')</code>
| <code>(''pack'' ''op'' ...)</code>
|

|- style="vertical-align: top;"
| [[CFML]]
| <code>obj.reduce(func,initial)</code>
|
| <code>obj.reduce(func)</code>
|
|

|- style="vertical-align: top;"
| [[Clojure]]
| <code>(reduce ''func'' ''initval'' ''list'')</code>
| <code>(reduce ''func'' ''initval'' (reverse ''list'))</code>
| <code>(reduce ''func'' ''list'')</code>
| <code>(reduce ''func" (reverse ''list''))</code>
|

|- style="vertical-align: top;"
| [[Common Lisp]]
| <code>(reduce ''func'' ''list'' :initial-value ''initval'')</code>
| <code>(reduce ''func'' ''list'' :from-end t :initial-value ''initval'')</code>
| <code>(reduce ''func'' ''list'')</code>
| <code>(reduce ''func'' ''list'' :from-end t)</code>
|

|- style="vertical-align: top;"
| [[Curl|Curl]]
| <code>{{TreeNode.''default'' ''treeNode'' ...} ''.to-Iterator''}</code>
| <code>{{TreeNode.''default'' ''treeNode'' ...} ''.reverse}<wbr/>.{{nobr|to-Iterator}}''}</code>
| <code>{for {treeNode''<wbr/>.{{nobr|to-Iterator}}}'' ''do}''</code>
| <code>{for {{treeNode.reverse}''<wbr/>.{{nobr|to-Iterator}}}'' ''do}''</code>
|

|- style="vertical-align: top;"
| [[D|D]]
| <code>reduce!''func''(''initval'', ''list'')</code>
| <code>reduce!''func''(''initval'', ''list''<wbr/>.reverse)</code>
| <code>reduce!''func''(''list'')</code>
| <code>reduce!''func''(<wbr/>''list''.reverse)</code>
|

|- style="vertical-align: top;"
| [[Elixir|Elixir]]
| <code>List.foldl(list, acc, fun)</code>
| <code>List.foldr(list, acc, fun)</code>
|
|
|

|- style="vertical-align: top;"
| [[Elm|Elm]]
| <code>List.foldl(''Fun'', ''Accumulator'', ''List'')</code>
| <code>List.foldr(''Fun'', ''Accumulator'', ''List'')</code>
|
|
|

|- style="vertical-align: top;"
| [[Erlang|Erlang]]
| <code>lists:foldl(''Fun'', ''Accumulator'', ''List'')</code>
| <code>lists:foldr(''Fun'', ''Accumulator'', ''List'')</code>
|
|
|

|- style="vertical-align: top;"
| [[F Sharp|F#]]
| <code>Seq/List.fold ''func'' ''initval'' ''list''</code>
| <code>List.foldBack ''func'' ''list'' ''initval''</code>
| <code>Seq/List.reduce ''func'' ''list''</code>
| <code>List.reduceBack ''func'' ''list''</code>
| <code>Seq.unfold ''func'' ''initval''</code>

|- style="vertical-align: top;"
| [[Gosu|Gosu]]
| <code>''Iterable''.fold(''f''(agg, e))<wbr/>''Iterable''.reduce(init, ''f''(agg, e)) <wbr/>''Iterable''.partition(''f''(e))</code>
|
|
|
|

|- style="vertical-align: top;"
| [[Groovy|Groovy]]
| <code>''list''<wbr/>.inject(''initval'', ''func'')</code>
| <code>''list''.reverse()<wbr/>.inject(''initval'', ''func'')</code>
| <code>''list''<wbr/>.inject(''func'')</code>
| <code>''list''.reverse()<wbr/>.inject(''func'')</code>
|

|- style="vertical-align: top;"
| [[Haskell|Haskell]]
| <code>foldl ''func'' ''initval'' ''list''</code>
| <code>foldr ''func'' ''initval'' ''list''</code>
| <code>foldl1 ''func'' ''list''</code>
| <code>foldr1 ''func'' ''list''</code>
| <code>unfoldr ''func'' ''initval''</code>

|- style="vertical-align: top;"
| [[Haxe]]
| <code>Lambda.fold(''iterable'', ''func'', ''initval'')</code>
|
|
|
|

|- style="vertical-align: top;"
| [[J|J]]
| <code>''verb''<nowiki>~/|.</nowiki> ''initval'',''array''</code>
| <code>''verb''/ ''array'',''initval''</code>
| <code>''verb''<nowiki>~/|.</nowiki> ''array''</code>
| <code>''verb''/ ''array''</code>
|

|- style="vertical-align: top;"
| [[Java|Java]] 8+
| <code>''stream''.reduce<wbr/>(''initval'', ''func'')</code>
|
| <code>''stream''.reduce<wbr/>(''func'')</code>
|
|

|- style="vertical-align: top;"
| [[JavaScript]] 1.8<br>[[ECMAScript]] 5
| <code>''array''.reduce<wbr/>(''func'', ''initval'')</code>
|
| <code>''array''.reduce<wbr/>(''func'')</code>
|
|

|- style="vertical-align: top;"
| [[Julia|Julia]]
| <code>foldl(''op'', ''itr''; [init])</code>
| <code>foldr(''op'', ''itr''; [init])</code>
| <code>foldl(''op'', ''itr'')</code>
| <code>foldr(''op'', ''itr'')</code>
|

|-
| [[Kotlin|Kotlin]]
| <code>''Iterable''.fold<wbr />(''initval'', ''func'')</code>
| <code>''Iterable''.foldRight<wbr />(''initval'', ''func'')</code>
| <code>''Iterable''.reduce''(func'')</code>
| ''<code>Iterable</code>''<code>.reduceRight''(func'')</code>
|

|- style="vertical-align: top;"
| [[LFE|LFE]]
| <code>(lists:foldl ''func'' ''accum'' ''list'')</code>
| <code>(lists:foldr ''func'' ''accum'' ''list'')</code>
|
|
|

|- style="vertical-align: top;"
| [[Logtalk]]
| <code>fold_left(Closure, Initial, List, Result)</code>
| <code>fold_right(Closure, Initial, List, Result)</code>
|
|
|

|- style="vertical-align: top;"
| [[Maple (software)|Maple]]
| <code>foldl(''func'', ''initval'', ''sequence'')</code>
| <code>foldr(''func'', ''initval'', ''sequence'')</code>
|
|
|

|- style="vertical-align: top;"
| [[Mathematica]]
| <code>Fold[''func'', ''initval'', ''list'']</code>
| <code>Fold[''func'', ''initval'', Reverse[''list'']]</code>
| <code>Fold[''func'', ''list'']</code>
| <code>Fold[''func'', Reverse[''list'']]</code>
| <code>NestWhileList[''func,'', ''initval'', ''predicate'']</code>

|- style="vertical-align: top;"
| [[MATLAB]]
| <code>fold(@''func'', ''list'', ''defaultVal'')</code>
| <code>fold(@''func'', flip(''list''), ''defaultVal'')</code>
| <code>fold(@''func'', ''list'')</code>
| <code>fold(@''func'', flip(''list''))</code>
| <code></code>

|- style="vertical-align: top;"
| [[Maxima (software)|Maxima]]
| <code>lreduce(''func'', ''list'', ''initval'')</code>
| <code>rreduce(''func'', ''list'', ''initval'')</code>
| <code>lreduce(''func'', ''list'')</code>
| <code>rreduce(''func'', ''list'')</code>
|

|- style="vertical-align: top;"
| [[Mythryl]]
| <code>fold_left ''func'' ''initval'' ''list''<br /> vector::fold_left ''func'' ''initval'' ''vector''</code>
| <code>fold_right ''func'' ''initval'' ''list''<br /> vector::fold_right ''func'' ''initval'' ''vector''</code>
|
|
|

|- style="vertical-align: top;"
| [[OCaml]]
| <code>List.fold_left ''func'' ''initval'' ''list''<br /> Array.fold_left ''func'' ''initval'' ''array''</code>
| <code>List.fold_right ''func'' ''list'' ''initval''<br /> Array.fold_right ''func'' ''array'' ''initval''</code>
|
|
| <code>Base.Sequence.unfold ''~init'' ''~f''</code><ref>{{웹 인용|url=https://opensource.janestreet.com/base/|title = Base|publisher = Jane Street Capital|access-date = February 26, 2019}}</ref>

|- style="vertical-align: top;"
| [[Oz|Oz]]
| <code>{FoldL ''List'' ''Func'' ''InitVal''}</code>
| <code>{FoldR ''List'' ''Func'' ''InitVal''}</code>
|
|
|

|- style="vertical-align: top;"
| [[PARI/GP]]
| <code>fold( ''f'', ''A'' )</code>
|
|
|
|

|- style="vertical-align: top;"
| [[Perl]]
| <code>reduce ''block'' ''initval'', ''list''</code>
|
| <code>reduce ''block'' ''list''</code>
|
|

|- style="vertical-align: top;"
| [[PHP]]
| <code>array_reduce(''array'', ''func'', ''initval'')</code>
| <code>array_reduce(<wbr/>array_reverse(''array''), ''func'', ''initval'')</code>
| <code>array_reduce(''array'', ''func'')</code>
| <code>array_reduce(<wbr/>array_reverse(''array''), ''func'')</code>
|

|- style="vertical-align: top;"
| [[Python|Python]] 2.x
| <code>reduce(''func'', ''list'', ''initval'')</code>
| <code>reduce(lambda x,y: ''func''(y,x), reversed(''list''), ''initval'')</code>
| <code>reduce(''func'', ''list'')</code>
| <code>reduce(lambda x,y: ''func''(y,x), reversed(''list''))</code>
|

|- style="vertical-align: top;"
| [[Python|Python]] 3.x
| <code>functools.reduce(''func'', ''list'', ''initval'')</code>
| <code>functools.reduce(lambda x,y: ''func''(y,x), reversed(''list''), ''initval'')</code>
| <code>functools.reduce(''func'', ''list'')</code>
| <code>functools.reduce(lambda x,y: ''func''(y,x), reversed(''list''))</code>
|

|- style="vertical-align: top;"
| [[R|R]]
| <code>Reduce(''func'', ''list'', ''initval'')</code>
| <code>Reduce(''func'', ''list'', ''initval'', right=TRUE)</code>
| <code>Reduce(''func'', ''list'')</code>
| <code>Reduce(''func'', ''list'', right=TRUE)</code>
|

|- style="vertical-align: top;"
| [[Ruby|Ruby]]
| <code>''enum''<wbr/>.inject(''initval'', ''&block'')<br /> ''enum''<wbr/>.reduce(''initval'', ''&block'')</code>
| <code>''enum''.reverse_each<wbr/>.inject(''initval'', ''&block'')<br /> ''enum''.reverse_each<wbr/>.reduce(''initval'', ''&block'')</code>
| <code>''enum''<wbr/>.inject(''&block'')<br /> ''enum''.reduce(''&block'')</code>
| <code>''enum''.reverse_each<wbr/>.inject(''&block'')<br /> ''enum''.reverse_each<wbr/>.reduce(''&block'')</code>
|

|- style="vertical-align: top;"
| [[Rust|Rust]]
| <code>''iterator''.fold(''initval'', ''func'')</code>
| <code>''iterator''.rev().fold(''initval'', ''func'')</code>
|
|
|

|- style="vertical-align: top;"
| [[Scala|Scala]]
| <code>''list''.foldLeft(''initval'')(''func'')</code><br /><code>(''initval'' /: ''list'')(''func'')</code>
| <code>''list''.foldRight(''initval'')(''func'')</code><br /><code>(''list'' :\ ''initval'')(''func'')</code>
| <code>''list''.reduceLeft(''func'')</code>
| <code>''list''.reduceRight(''func'')</code>
|

|- style="vertical-align: top;"
| [[Scheme|Scheme]] R<sup>6</sup>RS
| <code>(fold-left ''func'' ''initval'' ''list'')<br /> (vector-fold ''func'' ''initval'' ''vector'')</code>
| <code>(fold-right ''func'' ''initval'' ''list'')<br /> (vector-fold-right ''func'' ''initval'' ''vector'')</code>
| <code>(reduce-left ''func'' ''defaultval'' ''list'')</code>
| <code>(reduce-right ''func'' ''defaultval'' ''list'')</code>
| <code>(unfold ''p'' ''f'' ''g'' ''seed'' ''[tail-gen]'')</code><br /><code>unfold-right ''p'' ''f'' ''g'' ''seed'' ''[tail]''</code><br /><code>(vector-unfold ''f'' ''length'' ''initial-seed'' ''···'')</code><br /><code>(vector-unfold-right ''f'' ''length'' ''initial-seed'' ''···'')</code>

|- style="vertical-align: top;"
| [[스몰토크]]
| <code>''aCollection'' inject: ''aValue'' into: ''aBlock''</code>
|
| <code>''aCollection'' reduce: ''aBlock''</code>
|
|

|- style="vertical-align: top;"
| [[Standard ML]]
| <code>foldl ''func'' ''initval'' ''list''<br /> Array.foldl ''func'' ''initval'' ''array''</code>
| <code>foldr ''func'' ''initval'' ''list''<br /> Array.foldr ''func'' ''initval'' ''array''</code>
|
|
|

|- style="vertical-align: top;"
| [[Swift|Swift]]
| <code>''array''.reduce(''initval'', ''func'')<br /> reduce(''sequence'', ''initval'', ''func'')</code>
| <code>''array''.reverse()<wbr/>.reduce(''initval'', ''func'')</code>
|
|
|

|- style="vertical-align: top;"
| [[XPath 3|XPath 3.1]]
| {{sxhl|2=xquery|
array:fold-left(
  $array as array(*),
  $zero as item()*,
  $f as function(
    item()*, item()*
  } as item()*
) as item()*
}}<ref>[https://www.w3.org/TR/xpath-functions-31/#func-array-fold-left ''array'':fold-left]</ref>

{{sxhl|2=xquery|
fn:fold-left(
  $seq as item()*,
  $zero as item()*,
  $f as function(
    item()*, item()
  ) as item()*
) as item()*
}}<ref>[https://www.w3.org/TR/xpath-functions-31/#func-fold-left fold-left]</ref>

| {{sxhl|2=xquery|
array:fold-right(
  $array as array(*),
  $zero as item()*,
  $f as function(
    item()*, item()*
  } as item()*
) as item()*
}}<ref>[https://www.w3.org/TR/xpath-functions-31/#func-array-fold-right ''array'':fold-right]</ref>

{{sxhl|2=xquery|
fn:fold-right(
  $seq as item()*,
  $zero as item()*,
  $f as function(
    item(), item()*
  ) as item()*
) as item()*
}}<ref>[https://www.w3.org/TR/xpath-functions-31/#func-fold-right fold-right]</ref>

|
|
|

|- style="vertical-align: top;"
| [[Xtend]]
| <code>''iterable''.fold(''initval'',[''func''])</code>
|
| <code>''iterable''.reduce[''func'']</code>
|
|
|}

== 같이 보기 ==
* [[준동형]]
* [[Map (고차 함수)]]
* [[재귀 (컴퓨터 과학)]]

== 각주 ==
{{각주}}

{{전거 통제}}

[[분류:고차 함수]]
[[분류:재귀]]