重畳関数とは、高階関数の一種である。関数型プログラミングでよく用いられる。
関数名としてはfold, inject, reduceなどがよく用いられる。プログラミング言語により関数名の違いが大きい。畳み込みと呼ぶこともあるが、日本語では畳み込みは数学の違う計算
を指すことがあるもよう。
初期値と、リストと、「引数を2つとる関数」を引数にとる。「引数を2つとる関数」は正確には「関数自身の戻り値と同じ型の引数と、リストの1要素を引数とする関数」である。
式で書くと以下のような感じである。
fold(ini, list, f): ini は初期値、list は a1, a2, ..., an からなるリスト、f は関数 であるとき、
r1 = f(ini, a1), r2 = f(r1, a2), r3 = f(r2, a3), ..., rn = f(rn-1, an)とするとfold(ini, list, f) = rnである。
抽象的すぎてわかりづらい方のために簡単な例をあげると、「1からnまでの総和を求める関数」を重畳関数で表現することができる。
初期値を0、リストをnまでの自然数からなるリスト[1, 2, ..., n]、関数f(a, b) = a + b とすると、
r1 = f(0, 1) = 0 + 1, r2 = f(r1, 2) = 0 + 1 + 2, r3 = f(r2, 3) = 0 + 1 + 2 + 3, ..., となり、fold(0, [1, 2, ..., n], f)が「1からnまでの総和」になることがわかる。
ちなみに初期値を1、f(a, b) = a × b とすると、n の階乗を求める関数に早変わりする。
さらにもう少し具体的に、上記の総和を求める例で n = 5 とすると、
fold(0, [1, 2, 3, 4, 5], +) = (((((0 + 1)+2)+3)+4)+5)
ということであり、これを図示すると、下記のようになる。
| 初期値 | リスト | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | [ | 1 | , | 2 | , | 3 | , | 4 | , | 5 | ] | |
| 0 | + | 1 | ||||||||||
| ↓ | 0 + 1 = 1 | |||||||||||
| 1 | + | 2 | ||||||||||
| ↓ | 1 + 2 = 3 | |||||||||||
| 3 | + | 3 | ||||||||||
| ↓ | 3 + 3 = 6 | |||||||||||
| 6 | + | 4 | ||||||||||
| ↓ | 6 + 4 = 10 | |||||||||||
| 10 | + | 5 | ||||||||||
| ↓ | 10 + 5 = 15 | |||||||||||
| 15 | = | fold(0, [1, 2, 3, 4, 5], +) | ||||||||||
このように、リストの要素が戻り値の中に畳み込まれていく(注入されていく)イメージからfold(あるいはinject)という関数名が用いられたり、複数の値からなるリストが要素数を「減らして」たった一つの値に集約されることからreduceという関数名が用いられると思われる。
リストの末尾から計算する重畳関数というものもある。fold_rightやreducerのように末尾にrightやrをつけて表現することが多い。また、これと区別するために先頭から計算する方をfoldlとかreduce_leftのような表現をすることもある。
上記具体例で言えば、
fold_right(0, [1, 2, 3, 4, 5], +) = (1+(2+(3+(4+(5+0)))))
となる。足し算は交換法則や結合法則が成り立つのでfoldとfold_rightの結果は等しくなるが、関数の種類によっては答えが変わってくる。
掲示板
2 ななしのよっしん
2017/06/18(日) 16:13:46 ID: VXWgIXXfki
3 ななしのよっしん
2017/11/19(日) 12:30:16 ID: 6CBkk22mnL
A「たくさんの数を足す時って今まで足した数に次の数足して計算するやろ?」
B「うん」
A「これは掛け算でも一緒やねん」
B「確かに」
A「よって、足し算掛け算その他なんでもええから、XXX(今までの計算結果、次の値)を順々にやらすのが重畳関数や」
B「ん?今なんでもって?」
A「そらそうよ。(foldがあればmapとかも)アレできるねん。エライんやで」
B「そうかー」
4 ななしのよっしん
2024/02/24(土) 23:19:09 ID: JNzGTqjhxf
リストを受け取って一個にまとめて返す関数のことやろ
なんでこんな難しくなんねんな
関数型齧ったヤツは抽象の説明でイキリがちだから困るわ
みんながみんなライブラリ作るわけじゃないんだから、いらんねんその概念
いる奴はもっとマシなとこで勉強するしな
急上昇ワード改
最終更新:2025/12/06(土) 15:00
最終更新:2025/12/06(土) 15:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。