これは、マップと折り畳みの説明に役立つ補足的な回答です。以下の例では、このリストを使用します。このリストは不変であるため、変更されることはありません。
var numbers = [1, 2, 3, 4, 5]
コードを読みやすくするため、例では数字を使用します。ただし、折り畳みは、従来の命令型ループを使用できるものなら何でも使用できます。
マップは、何かのリストを受け取り、機能、および機能を使用して変更されたリストを返します。各アイテムは関数に渡され、関数が返すものになります。
これの最も簡単な例は、リスト内の各番号に番号を追加するだけです。疑似コードを使用して、言語に依存しないようにします。
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
を印刷するとnumbers2
、[3, 4, 5, 6, 7]
各要素に2が追加された最初のリストが表示されます。使用する関数add-two
が指定されmap
ていることに注意してください。
Foldは似ていますが、それらを与えるために必要な関数は2つの引数を取る必要があります。通常、最初の引数はアキュムレータです(最も一般的なのは左折です)。アキュムレーターは、ループ中に渡されるデータです。2番目の引数は、リストの現在のアイテムです。上記のmap
関数のように。
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
印刷sum
すると、数字のリストの合計が表示されます:15。
引数fold
は次のとおりです。
これは、フォールドに与えている関数です。フォールドは、関数に現在のアキュムレーターとリストの現在のアイテムを渡します。関数が返すものはすべて新しいアキュムレータになり、次回に関数に渡されます。これは、FPスタイルをループしているときに値を「記憶」する方法です。私はそれに2つの数字を取り、それらを追加する機能を与えました。
これが最初のアキュムレーターです。リスト内のアイテムが処理される前のアキュムレーターの起動。数字を合計するとき、数字を合計する前の合計はいくらですか?0、2番目の引数として渡した。
最後に、マップと同様に、処理する番号のリストも渡します。
それでも折り目が意味をなさない場合は、これを考慮してください。あなたが書くとき:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
基本的には、渡された関数をリスト内の各アイテムの間に置き、左または右のいずれかに初期アキュムレーターを追加します(左または右の折り目によって異なります)。
[1, 2, 3, 4, 5]
になる:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
これは15です。
使う map
あるリストを同じ長さの別のリストに変換場合はます。
使う fold
あなたは番号のリストを合計するように、1つの値にリストを有効にしたいとき。
@Jorgがコメントで指摘したように、「単一の値」は数字のような単純なものである必要はありません。リストやタプルを含む、単一のオブジェクトでもかまいません!実際に折り畳みをクリックする方法は、折り畳みに関してマップを定義することでした。アキュムレータがリストであることに注意してください。
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
正直なところ、それぞれを理解すれば、ほとんどすべてのループをフォールドまたはマップに置き換えることができることに気付くでしょう。