在(减少f val coll)中,val是累加器吗?

Ced*_*tin 10 reduce clojure accumulator

当你调用reduce并传递一个函数和两个参数时,第一个参数可以被认为是一个累加器吗?

总是一个累加器吗?

有时是累加器吗?

我正在阅读一篇关于使用Clojure来解析大文件的博客文章并找到了这一行:

(reduce line-func line-acc (line-seq rdr))
Run Code Online (Sandbox Code Playgroud)

链接到博客条目:

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

怎么样简单:( 减少+ [1 2 3])?是否涉及累加器?

我把它问题归结为:"什么是累加器?"

但我还是想了解累加器和reduce函数之间的关系.所以对这些特定(相关)问题的任何答案都是最受欢迎的!

Leo*_*nel 5

在(减少f val coll)中,val是累加器吗?

不,这是函数f的论证.这意味着f应用于val和coll中的第一个元素.

例如:

(reduce + 1 [2 3 4])        ;; 10
(reduce + (cons 1 [2 3 4])) ;; 10
Run Code Online (Sandbox Code Playgroud)

怎么样简单:(减少+ [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)
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,最内部调用都f需要参数1和2?在第一种情况下,1和2是coll的第一和第二元素; 在第二种情况下,1是唯一值,2是coll的第一个元素.

什么是累加器?

累加器是保存计算的中间结果的变量.就像在Java片段中一样:

int sum = 0;
for (int i = 0; i < 10; i++) {
    sum += i;
}
return sum;
Run Code Online (Sandbox Code Playgroud)

这里,变量sum的值随着循环的进行而改变.在Clojure中,变量是不可变的,所以你没有看到这个成语.相反,累加器通常(但不总是)是递归函数的参数.

例如,这是一个通过将列表中的第一个条目"累积"到累加器前面来反转列表的函数.在这种情况下,变量不会更改,但会传递给该函数的另一个调用.

(defn reverse [[f & r] acc]
  (if (nil? f)
    acc
    (recur r (conj acc f))))

(reverse [1 2 3] ()) ;; [3 2 1]
Run Code Online (Sandbox Code Playgroud)


mik*_*era 5

它可以是一个累加器。

这取决于您如何使用它,以及您对“累加器”的定义。

这是一个传统的可变累加器,请注意需要在每一步继续传递相同的累加器:

(reduce 
  (fn [atom val] (do (swap! atom + val) atom))
  (atom 10)
  [1 2 3 4 5])
=> #<Atom@115872f5: 25>
Run Code Online (Sandbox Code Playgroud)

这里的 reduce 与不可变的“累加器”一起使用。尽管传统上累加器是可变的,但我认为大多数函数式程序员会将其定义为累加器:

(reduce + 10 [1 2 3 4 5])
=> 25
Run Code Online (Sandbox Code Playgroud)

这是一个你不累积任何东西的减少,所以很难证明第二个参数是一个累加器:

(reduce 
  (fn [_ x] (println x))
  nil 
  [1 2 3])
Run Code Online (Sandbox Code Playgroud)