Fold(高階関数)

関数型プログラミングにおいてフォールドとは、再帰的なデータ構造を分析し与えられた結合演算を用いて、その構成要素を再帰的に処理した結果を再結合し、戻り値を構築する高階関数です。フォールドは、 reduceaccumulateaggregatecompressinjectとも呼ばれます。通常、フォールドは、結合関数、データ構造最上位ノード、そして場合によっては特定の条件下で使用されるデフォルト値とともに提示されます。その後、フォールドは、関数を体系的に使用して、 データ構造の階層構造の要素を結合していきます。

Fold はある意味ではunfoldの二重例です。unfold はシード値を受け取り、関数をコアクシブに適用して、コアクシブなデータ構造を段階的に構築する方法を決定します。一方、fold は構造を再帰的に分解し、各ノードでその終端値と再帰結果に結合関数を適用した結果に置き換えます( catamorphism、これに対してunfold はanamorphismです)。

構造的変化として

折り畳みは、データ構造の構造コンポーネントを一貫して関数と値に置き換えることと見なすことができます。たとえば、リストは多くの関数型言語で 2 つのプリミティブから構築されます。すべてのリストは、一般にnil   ( []) と呼ばれる空のリスト、または別のリストの前に要素を付加してコンスノード( Cons(X1,Cons(X2,Cons(...(Cons(Xn,nil))))) と呼ばれるものを作成することによって構築されます。これは、関数 ( Haskell ではconsコロンとして記述されます) の適用の結果として生成されます。リストの折り畳みは、リストの末尾の nil を特定の値に置き換え、  各コンス特定の関数に置き換えることと見なすことができます。これらの置き換えは、次の図で確認できます。(:)

構造変換を一貫した方法で実行する別の方法があります。結合関数に入力するときに、各ノードの 2 つのリンクの順序を反転します。

これらの図は、リストの右折り畳みと左折り畳みを視覚的に示しています。また、 がfoldr (:) []リストの恒等関数(Lisp用語では浅いコピー)であるという事実も強調しています。これは、consを にnilを に置き換えても結果が変わらないためです。左折り畳みの図は、リスト を反転する簡単な方法を示しています。追加する要素が結合関数の右側のパラメータになったため、 cons のパラメータを反転する必要があることに注意してください。この観点からわかるもう1つの簡単な結果は、 を持つ要素に作用する関数を で構成することにより、に関して高階マップ関数を記述することです。consnilfoldl (flip (:)) []foldrcons

 マップf = foldr (( : ) . f ) []       

ここで、ピリオド (.) は関数の合成を表す演算子です。

この考え方は、様々な種類の木のような他の代数的データ型や構造に対して、foldのような関数を設計するためのシンプルな方法を提供します。データ型の構築子を与えられた関数に、そしてその型の定数値を与えられた値に再帰的に置き換える関数を記述します。このような関数は一般にcatamorphismと呼ばれます。

リストに載る

リストを[1,2,3,4,5]加算演算子で畳み込むと、リストの要素の合計である15が得られます。大まかに言えば、この畳み込みはリスト内のカンマを+演算子に置き換えたものと考えることができます。つまり、リストの[1,2,3,4,5]要素の合計は15になります。 [1]1 + 2 + 3 + 4 + 5

上記の例では、+ は結合演算なので、計算方法が異なっていても、括弧で囲んでも最終結果は同じになります。 非結合的な二項関数の一般的なケースでは、要素が結合される順序が最終結果の値に影響を与える可能性があります。 リストでは、これを実行する 2 つの明らかな方法があります。最初の要素を残りの要素を再帰的に結合した結果と結合する方法 (右折り畳みと呼ばれる)、または最後の要素を除くすべての要素を再帰的に結合した結果を最後の要素と結合する方法 (左折り畳みと呼ばれる) です。これは、 HaskellまたはPrologの用語では、二項演算子が右結合または左結合であることに対応します。右折り畳みの場合、合計は のように括弧で囲まれますが、左折り畳みの場合、合計は のように括弧で囲まれます1 + (2 + (3 + (4 + 5)))(((1 + 2) + 3) + 4) + 5

実際には、初期値を持つことが便利で自然です。右折り畳みの場合はリストの末尾に到達したときに使用され、左折り畳みの場合はリストの最初の要素と最初に結合される値です。上記の例では、値0(加法単位元)が初期値として選択され、1 + (2 + (3 + (4 + (5 + 0))))右折り畳みの場合は 、((((0 + 1) + 2) + 3) + 4) + 5左折り畳みの場合は となります。乗算の場合、初期値として0を選択しても は機能しません。0 * 1 * 2 * 3 * 4 * 5 = 0。乗算の単位元は1です。したがって、結果は となります1 * 1 * 2 * 3 * 4 * 5 = 120 = 5!

線状折りと樹状折り

結合関数f の  型が非対称な場合(例:a → b → b)、つまり結果の型がリストの要素の型と異なる場合、初期値を使用する必要があります。その場合、線形チェーンの適用を可能にするには、 f の結果と同じ型の初期値を使用する必要があります。それが左向きか右向きかは、結合関数が引数に期待する型によって決まります。2番目の引数が結果と同じ型でなければならない場合、f は右向き に を関連付ける  二項演算と見なすことができ、その逆も同様です。

関数がマグマ、すなわち型が対称的(a → a → a)であり、結果の型がリスト要素の型と同じ場合、括弧は任意の形式で配置できるため、ネストされた部分式の二分木((1 + 2) + (3 + 4)) + 5が作成されます(例: ) 。二項演算fが結合的である場合、この値は明確に定義されます(つまり、括弧で囲んでも同じ値になりますが、計算方法の詳細は異なります)。 f  が非正格な  場合、これは効率に大きな影響を与える可能性があります

線形フォールドはノード指向であり、リストの各ノードに対して一貫した方法で動作しますが、ツリー状のフォールドはリスト全体指向であり、ノードのグループ間で一貫した方法で動作します。

空でないリストのための特別な折り畳み

演算fの単位元を初期値zとして選択したい場合がよくあります。適切な初期値が見つからない場合、例えば、2つのパラメータの最大値を計算する関数を空でないリストに対して畳み込み、リストの最大要素を取得したい場合など、リストの最後と最初の要素をそれぞれ初期値として使用する と の変種があります。Haskellや他のいくつかの言語では、これらは と と呼ばれ1は初期要素の自動生成と、それらが適用されるリストが少なくとも1つの要素を持つ必要があることを意味します。foldrfoldlfoldr1foldl1

これらのフォールドは型対称二項演算を使用します。つまり、引数と結果の型は同じでなければなりません。リチャード・バードは2010年の著書[2]で、「空でないリスト上の汎用フォールド関数」を提案していますfoldrn。この関数は、フォールド処理を開始する前に、最後の要素に追加の引数関数を適用することで、結果の型の値に変換します。これにより、通常のフォールドと同様に型非対称二項演算を使用して、foldrリストの要素の型とは異なる型の結果を生成することができます。

実装

線状の折り目

Haskell を例にすると、foldlいくつfoldrかの方程式で定式化できます。

 foldl :: ( b -> a -> b ) -> b -> [ a ] -> b foldl f z [] = z foldl f z ( x : xs ) = foldl f ( f z x ) xs                             

リストが空の場合、結果は初期値になります。そうでない場合は、リストの末尾を折り返し、古い初期値と最初の要素に f を適用した結果を新しい初期値として使用します。

 foldr :: ( a -> b -> b ) -> b -> [ a ] -> b foldr f z [] = z foldr f z ( x : xs ) = f x ( foldr f z xs )                             

リストが空の場合、結果は初期値zになります。そうでない場合は、最初の要素にfを適用し、残りの要素を畳み込んだ結果になります。

木のような折り目

リストは、有限リストと無期限リストの両方において、ツリー状に折り畳むことができます。

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                                                       

関数の場合、無期限にfoldi定義されたリストに対する暴走評価を回避するために、関数は2 番目の引数の値を常に要求してはならず、少なくともそのすべてを要求したり、即時に要求したりしてはなりません (以下の例を参照)。f

空でないリストの折り畳み

foldl1 f [ x ] = x foldl1 f ( x : y : xs ) = foldl1 f ( f x y : xs )              foldr1 f [ x ] = x折り返しf ( x : xs ) = f x (折り返しf xs )            foldt1 f [ x ] = x foldt1 f ( x : y : xs ) = foldt1 f ( f x y :ペアf xs ) foldi1 f [ x ] = x foldi1 f ( x : xs ) = f x ( foldi1 f (ペアf xs ))                               

評価順序の考慮事項

遅延評価、つまり非厳密評価が存在する場合はリストの先頭へのffoldrの適用と、リストの残りの部分に対する再帰的な折り返しを直ちに返します。したがって、 f が「右側」の再帰ケース、つまり2 番目の引数を参照せずに結果の一部を生成でき、結果の残りの部分が要求されない場合、再帰は停止します (例: )。これにより、右折り返しを無限リストで操作できます。対照的に、 は、リストの末尾に達するまで、新しいパラメータを使用して自分自身を直ちに呼び出します。この末尾再帰はループとして効率的にコンパイルできますが、無限リストをまったく処理できず、無限ループで永久に再帰することになりますhead == foldr (\a b->a) (error "empty list")foldl

リストの末尾に到達すると、ネストされた左深化の-適用によって式が事実上構築され、それが呼び出し元に渡されて評価されます。関数がここで最初に 2 番目の引数を参照し、再帰ケース (ここではその左側、つまり最初の引数)を参照せずに結果の一部を生成できる場合、再帰は停止します。つまり、 が右側で再帰している間、遅延結合関数を使用してリストの要素を左側から検査できます。逆に、 が左側で再帰している間、遅延結合関数を使用してリストの要素を右側から検査することもできます (そのように選択した場合、例: )。foldlfffoldrfoldllast == foldl (\a b->b) (error "empty list")

リストの反転も末尾再帰です( を使用して実装できます)。有限リストでは、これは left-fold と reverse を組み合わせて末尾再帰的な方法で right fold を実行することができることを意味します( を参照  )。そのためには関数を変更して引数の順序を逆にし(つまり、)、末尾再帰的に rightfold が構築する式の表現を構築します。不要な中間リスト構造は継続渡しスタイルのテクニックで削除できます。同様に、( は、 の結合関数への引数の順序が反転する Haskell などの言語でのみ必要です。一方、Scheme では、と の両方への結合関数に同じ引数の順序が使用されています)。rev = foldl (\ys x -> x : ys) []1+>(2+>(3+>0)) == ((0<+3)<+2)<+1ffoldr f z == foldl (flip f) z . foldl (flip (:)) []foldr f z xs == foldl (\k x-> k . f x) id xs zfoldl f z xs == foldr (\x k-> k . flip f x) id xs zflipfoldlfoldlfoldr

もう 1 つの技術的なポイントは、遅延評価を使用する左折り畳みの場合、新しい初期パラメータは再帰呼び出しが行われる前に評価されないことです。これにより、リストの末尾に到達し、結果として得られる潜在的に巨大な式を評価しようとする際に、スタック オーバーフローが発生する可能性があります。このため、このような言語では、再帰呼び出しを行う前に初期パラメータの評価を強制する、より厳格な左折り畳みの変種が提供されることがよくあります。Haskell では、これはライブラリfoldl'内の (アポストロフィに注意。「プライム」と発音します) 関数ですData.List(ただし、遅延データ コンストラクターで構築された値を強制しても、その構成要素が自動的に強制されるわけではないことに注意してください)。末尾再帰と組み合わせると、このような折り畳みはループの効率に近づき、最終結果の遅延評価が不可能または望ましくない場合に、一定の空間での操作を保証します。

Haskellインタープリタを使用すると、fold 関数が実行する構造変換は、文字列を構築することによって説明できます。

λ > 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" (マップ表示[ 1 .. 13 ]) "(((((1+2)+(3+4))+((5+6)+(7+8)))+(((9+10)+(11+12))+13))+0)" λ > foldi ( \ x y -> concat [ "(" , x , "+" , y , ")" ]) "0" (マップ表示[ 1 .. 13 ]) "(1+((2+3)+(((4+5)+(6+7))+((((8+9)+(10+11))+(12+13))+0))))"                                           

無限の木のような折り畳みは、例えばHaskellエラトステネスの無限ふるいによる再帰的な素数生成で実証されています

素数= 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 . ...                                

ここで、関数はunion順序付きリストに対して局所的に操作し、それらの集合の和集合と差集合を効率的生成ますminus

素数の有限接頭辞は、列挙された整数の倍数のリスト上の差集合演算の畳み込みとして簡潔に定義され、

primesTo n = foldl1マイナス[[ 2 * x , 3 * x .. n ] | x <- [ 1 .. n ]]         

例えば有限リストの場合、マージソート(およびその重複除去型nubsort)は、木のような折り畳みを使って簡単に定義できる。

mergesort xs = foldt merge [] [[ x ] | x <- xs ] nubsort xs = foldt union [] [[ x ] | x <- xs ]                    

関数 は のmerge重複を保持する変形ですunion

関数headとをlast折り畳みによって次のように定義できる。

head = foldr ( \ x r -> x ) (エラー"head: 空のリスト" ) last = foldl ( \ a x -> x ) (エラー"last: 空のリスト" )                

さまざまな言語で

言語左折り右折り初期値なしの左折り初期値なしの右折り展開する注記
APLfunc⍨/initval,vectorfunc/vector,initvalfunc⍨/vectorfunc/vector
C# 3.0ienum.Aggregate(initval, func)ienum.Reverse().Aggregate(initval, func)ienum.Aggregate(func)ienum.Reverse().Aggregate(func)Aggregate拡張メソッドは、すべての.NET言語で同様
ienumIEnumerable<T>
C++std::accumulate(begin, end, initval, func)std::accumulate(rbegin, rend, initval, func)ヘッダー<numeric>
begin、、反復子でありend関数ポインタまたは関数オブジェクトになることができます。rbeginrend
func
C++17(initval op ... op pack)(pack op ... op initval)(... op pack)(pack op ...)Fold 式 (可変個引数テンプレートのみ):opは二項演算子 (両方opの は同じである必要があります。例: ) であり、は展開されていないパラメータ パックです。(std::cout << ... << args)pack
C++23std::ranges::fold_left(range, initval, func)std::ranges::fold_right(range, initval, func)std::ranges::fold_left_first(range, func)std::ranges::fold_right_last(range, func)std::ranges::fold_left_firstとは両方ともの空を考慮してstd::ranges::fold_right_last戻りますstd::optionalrange
CFMLobj.reduce(func, initial)obj.reduce(func)引数としてfunc、前の操作の結果(またはinitial最初の反復の値)、現在の項目、現在の項目のインデックスまたはキー、およびobj
クロージュア(reduce func initval list)(reduce func initval (reverse list))(reduce func list)(reduce func (reverse list))clojure.core.reducers/fold も参照してください。
コモンリスプ(reduce func list :initial-value initval)(reduce func list :from-end t :initial-value initval)(reduce func list)(reduce func list :from-end t)
Dreduce!func(initval, list)reduce!func(initval, list.reverse)reduce!func(list)reduce!func(list.reverse)モジュール内std.algorithm
エリクサーList.foldl(list, acc, fun)List.foldr(list, acc, fun)使用例についてはドキュメントを参照してください
エルムList.foldl(Fun, Accumulator, List)List.foldr(Fun, Accumulator, List)リストAPIも参照[1]
アーランlists:foldl(Fun, Accumulator, List)lists:foldr(Fun, Accumulator, List)
F#List.fold func initval list
Seq.fold func initval sequence
List.foldBack func list initvalList.reduce func list
Seq.reduce func sequence
List.reduceBack func listSeq.unfold func initval
輝きlist.fold(list, initial, func)
yielder.fold(yielder, initial, func)
list.fold_right(list, initial, func)list.reduce(list, func)
yielder.reduce(yielder, func)
yielder.unfold(initial, func)
ゴスIterable.fold(f(agg, e))
Iterable.reduce(init, f(agg, e))
Iterable.partition(f(e))
これらはすべてJavaのインターフェースの拡張メソッドIterableであり、配列もサポートされています。
グルーヴィーlist.inject(initval, func)list.reverse().inject(initval, func)list.inject(func)list.reverse().inject(func)
ハスケルfoldl func initval listfoldr func initval listfoldl1 func listfoldr1 func listunfoldr func initvalの場合foldl、折りたたみ関数は の場合と逆の順序で引数を取りますfoldr
ハックスLambda.fold(iterable, func, initval)
Jverb~/|. initval,arrayverb/ array,initvalverb~/|. arrayverb/ arrayu/yはyの項目間に2項uを適用します。「J辞書:挿入」
Java 8以降stream.reduce(initval, func)stream.reduce(func)
JavaScript 1.8
ECMAScript 5
array.reduce(func, initval)[3]array.reduceRight(func,initVal)array.reduce(func)array.reduceRight(func)リデューサーの主な引数は累積値と現在の値ですが、インデックスや配列などのオプションの引数を使用することもできます。array.reduceRight((acc, value, idx, array)=>{}, initvalue)
ジュリアfoldl(op, itr; [init])foldr(op, itr; [init])foldl(op, itr)foldr(op, itr)
コトリンIterable.fold(initval, func)Iterable.foldRight(initval, func)Iterable.reduce(func)Iterable.reduceRight(func)他のコレクションもfold[4][5]reduceをサポートしています。また[6 ]もあり、これは(成功または失敗)をおよびの戻り値の型に簡略化しますResult.fold(onSuccess, onFailure)Result<T>onSuccessonFailure
LFE(lists:foldl func accum list)(lists:foldr func accum list)
ログトークfold_left(Closure, Initial, List, Result)fold_right(Closure, Initial, List, Result)標準ライブラリオブジェクトによって提供されるメタ述語meta。略語foldlおよびfoldrも使用できます。
メープルfoldl(func, initval, sequence)foldr(func, initval, sequence)foldl(func, sequence)foldr(func, sequence)
マセマティカFold[func, initval, list]Fold[func, initval, Reverse[list]]Fold[func, list]Fold[func, Reverse[list]]NestWhileList[func,, initval, predicate]Fold初期値なしはバージョン 10.0 以降でサポートされます。
MATLABfold(@func, list, defaultVal)fold(@func, flip(list), defaultVal)fold(@func, list)fold(@func, flip(list))R2016b からサポートされている Symbolic Math Toolbox が必要です。
マキシマlreduce(func, list, initval)rreduce(func, list, initval)lreduce(func, list)rreduce(func, list)
OCamlList.fold_left func initval list
Array.fold_left func initval array
List.fold_right func list initval
Array.fold_right func array initval
オズ{FoldL List Func InitVal}{FoldR List Func InitVal}
PARI/GPfold( f, A )
パールreduce block initval, listreduce block listList::Utilモジュール
PHParray_reduce(array, func, initval)array_reduce(array_reverse(array), func, initval)array_reduce(array, func)array_reduce(array_reverse(array), func)が指定されていない場合はinitvalNULLが使用されるため、真のfoldl1ではありません。PHP 5.3より前では、initval整数のみを指定できます。はコールバックです。Wayback Machinefuncで2020年11月28日にアーカイブされています。array_reduceをオンラインでお試しください。
Python 2.xreduce(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.xfunctools.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))モジュールfunctools内。[7]
RReduce(func, list, initval)Reduce(func, list, initval, right=TRUE)Reduce(func, list)Reduce(func, list, right=TRUE)rightR は、関数のおよびinit引数を通じて、初期値の有無にかかわらず右折りたたみと左折りたたみまたは右折りたたみをサポートしますReduce
ラケット(foldl func initval list)(foldr func initval list)
ルビーenum.inject(initval, &block)
enum.reduce(initval, &block)
enum.reverse_each.inject(initval, &block)
enum.reverse_each.reduce(initval, &block)
enum.inject(&block)
enum.reduce(&block)
enum.reverse_each.inject(&block)
enum.reverse_each.reduce(&block)
Ruby 1.8.7+ では、ブロックの代わりに関数を表すシンボルを渡すこともできます。
enumは列挙体です。
これらの右折り畳みの実装は非可換であるため間違っていることに注意してください&block(初期値も間違った側に配置されます)。
さびiterator.fold(initval, func)iterator.rev().fold(initval, func)iterator.reduce(func)iterator.rev().reduce(func)iterator.rev()iteratorであることが必要であるDoubleEndedIterator[8]
スカラlist.foldLeft(initval)(func)
(initval /: list)(func)
list.foldRight(initval)(func)
(list :\ initval)(func)
list.reduceLeft(func)list.reduceRight(func)Scalaの記号的な折り畳み構文は、折り畳み操作を説明するために一般的に使用される左または右に傾いた木に似せることを意図していましたが[9]、その後、倒れるドミノの図として再解釈されました。[10]コロンは、一般的なScala構文メカニズムに由来しており、これにより、見かけ上のインフィックス演算子が、右オペランドを引数として渡した左オペランドのメソッドとして呼び出されます。または、演算子の最後の文字がコロンである場合は、その逆になります。ここでは対称的に適用されます。

Scalaではメソッドを使ったツリー状の折り畳みも特徴としていますlist.fold(z)(op)[11]

スキームR 6 RS(fold-left func initval list)
(vector-fold func initval vector)
(fold-right func initval list)
(vector-fold-right func initval vector)
(reduce-left func defaultval list)(reduce-right func defaultval list)(unfold p f g seed [tail-gen])
unfold-right p f g seed [tail]
(vector-unfold f length initial-seed ···)
(vector-unfold-right f length initial-seed ···)
srfi/1 srfi/43
雑談aCollection inject: aValue into: aBlockaCollection reduce: aBlockANSI Smalltalk では定義されていません#reduce:が、多くの実装では定義されています。
標準MLfoldl func initval list
Array.foldl func initval array
foldr func initval list
Array.foldr func initval array
指定された関数は、引数をタプルで受け取ります。 の場合foldl、折り畳み関数は の場合と同じ順序で引数を受け取りますfoldr
迅速array.reduce(initval, func)
reduce(sequence, initval, func)
array.reverse().reduce(initval, func)
XPathfold-left($input, $zero, $action)
array:fold-left($input, $zero, $action)
fold-right($input, $zero, $action)
array:fold-right($input, $zero, $action)
XPath は非構造化データに対してシーケンスを提供し、構造化データに対して配列を提供するため、各ケースに 2 つの関数が存在します
エクステンドiterable.fold(initval,[func])iterable.reduce[func]

普遍

Foldは多態的関数である。定義を持つ 任意のgに対して

 g [] = v g ( x : xs ) = f x ( g xs )          

gは次のように表される[12]

 g =折り畳みf v    

また、無限リストを持つ遅延言語では、固定小数点コンビネータをfoldを介して実装することができ、[13]反復をfoldに減らすことができることを証明しています。

 y f = foldr ( \ _ -> f ) undefined ( undefined の繰り返し)         

参照

参考文献

  1. ^ 「Haskellユニット6:高階フォールド関数 | Antoni Diller」www.cantab.net . 2023年4月4日閲覧
  2. ^ リチャード・バード、「機能的アルゴリズム設計の真珠」、ケンブリッジ大学出版局、2010年、 ISBN 978-0-521-51338-8、42ページ
  3. ^ "Array.prototype.reduce() - JavaScript | MDN". developer.mozilla.org . 2023年12月11日. 2024年1月16日閲覧
  4. ^ "fold - Kotlinプログラミング言語". Kotlin . Jetbrains . 2019年3月29日閲覧
  5. ^ "reduce - Kotlinプログラミング言語". Kotlin . Jetbrains . 2019年3月29日閲覧
  6. ^ 「Result - Kotlinプログラミング言語」Kotlin、Jetbrains 、 2019年3月29日閲覧
  7. ^ 参考functools.reduce:import functools
    参考reduce:from functools import reduce
  8. ^ “core::iter のイテレータ”. Rust . Rustチーム. 2021年6月22日閲覧
  9. ^ Odersky, Martin (2008年1月5日). 「Re: Blog: Scala言語に関する私の判断」.ニュースグループ: comp.scala.lang. 2015年5月14日時点のオリジナルよりアーカイブ。 2013年10月14日閲覧
  10. ^ Sterling, Nicholas (2010年7月28日). 「Scalaの/:演算子(foldLeft)の直感的な使い方」 . 2016年6月24日閲覧
  11. ^ 「Fold API - Scala標準ライブラリ」www.scala-lang.org . 2018年4月10日閲覧
  12. ^ Hutton, Graham (1999). 「fold の普遍性と表現力に関するチュートリアル」(PDF) . Journal of Functional Programming . 9 (4): 355– 372. doi :10.1017/S0956796899003500 . 2009年3月26日閲覧。
  13. ^ ポープ、バーニー. 「正しい折り目から修正する」(PDF) . The Monad.Reader (6): 5–16 . 2011年5月1日閲覧
  • 「高階関数 - マップ、フォールド、フィルター」
  • 「ユニット6:高階フォールド関数」
  • 「Tcl で折り畳む」
  • 「左折り畳みと右折り畳みからのリスト準同型性の構築」2009年4月13日アーカイブ、Wayback Machine
  • 「魔法の折り紙」
Retrieved from "https://en.wikipedia.org/w/index.php?title=Fold_(higher-order_function)&oldid=1319528177"