(reduce f val coll) で、val はアキュムレータですか?
いいえ、関数 f の引数です。これはf
、val と coll の最初の要素に適用されることを意味します。
例えば:
(reduce + 1 [2 3 4]) ;; 10
(reduce + (cons 1 [2 3 4])) ;; 10
単純な (reduce + [1 2 3]) はどうですか? アキュムレータが関係していますか?
いいえ、機能の一連のアプリケーションとしてですf
。このような:
(reduce f [1 2 3 4]) ; ==> (f (f (f 1 2) 3) 4)
(reduce f 1 [2 3 4]) ; ==> (f (f (f 1 2) 3) 4)
どちらの場合も、最も内側の への呼び出しf
がパラメーター 1 と 2 を取ることに注意してください。最初のケースでは、1 と 2 が coll の 1 番目と 2 番目の要素です。2 番目のケースでは、1 が唯一の値で、2 が coll の最初の要素です。
アキュムレータとは正確には何ですか?
アキュムレータは、計算の中間結果を保持する変数です。Java のこのスニペットのように:
int sum = 0;
for (int i = 0; i < 10; i++) {
sum += i;
}
return sum;
ここで、変数 sum の値は、ループが進行するにつれて変更されます。Clojure では、変数は不変であるため、このイディオムは表示されません。代わりに、アキュムレータは再帰関数へのパラメーターであることが多くなります (常にではありません)。
たとえば、リストの最初のエントリをアキュムレータの前に「蓄積」することで、リストを逆にする関数があります。この場合、変数は変更されませんが、関数の別の呼び出しに渡されます。
(defn reverse [[f & r] acc]
(if (nil? f)
acc
(recur r (conj acc f))))
(reverse [1 2 3] ()) ;; [3 2 1]