当您调用reduce并将其传递给一个函数和两个参数时,是否可以将第一个参数视为累加器?

它总是累加器吗?

有时是蓄能器吗?

我正在阅读有关使用Clojure解析大文件的博客条目,并发现以下行:

(reduce line-func line-acc (line-seq rdr))

链接到博客条目:

http://lethain.com/reading-file-in-clojure/

一个简单的怎么样:(reduce + [1 2 3])?是否有累加器?

我认为我的问题归结为:“什么是累加器?”

但是我仍然想了解累加器和reduce函数之间的关系。因此,对这些特定(相关)问题的任何答案都是最欢迎的!

最佳答案

在(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是lone值,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]

09-15 22:56