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函数之间的关系.所以对这些特定(相关)问题的任何答案都是最受欢迎的!
不,这是函数f的论证.这意味着f应用于val和coll中的第一个元素.
例如:
(reduce + 1 [2 3 4]) ;; 10
(reduce + (cons 1 [2 3 4])) ;; 10
Run Code Online (Sandbox Code Playgroud)
不,它是一系列功能应用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)
它可以是一个累加器。
这取决于您如何使用它,以及您对“累加器”的定义。
这是一个传统的可变累加器,请注意需要在每一步继续传递相同的累加器:
(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)