clojure.core.reducers / reduce的目的是什么?

时间:2016-03-12 19:47:09

标签: clojure

reduce引入了reducers的略微修改版本clojure.core.reducers/reducefirst(简r/reduce):

(defn reduce
  ([f coll]
   (reduce f (f) coll))
  ([f init coll]
   (if (instance? java.util.Map coll)
     (clojure.core.protocols/kv-reduce coll f init)
     (clojure.core.protocols/coll-reduce coll f init))))

r/reduce与其核心兄弟不同之处仅在于,当没有提供时,它使用(f)作为初始值,并且它为地图委派核心reduce-kv

我不明白这种奇怪的特殊用途reduce可能是什么用途以及为什么值得包含在redurs库中。

奇怪的是,据我所知,两篇介绍性博客文章中没有提到r/reducesecondhttp://en.wikipedia.org/wiki/Counting_sort)。官方文件说明

  

一般来说,大多数用户不会直接调用r / reduce,而应该更喜欢r / fold(...)但是,使用较少的中间结果执行急切减少可能很有用。

我不确定最后一句话暗示的是什么。

r/reduce可以处理核心减少的情况不是什么?我什么时候可以定罪r/reduce

1 个答案:

答案 0 :(得分:3)

两个可能的原因:

  1. 它有所不同 - 更好! - 在无初始顺序情况下,语义高于clojure.core/reduce在2014年Conj演示期间,Rich Hickey问道“当你用集合调用它时没有初始值时,谁知道reduce的语义是什么? ?” - follow this link for the exact spot in the presentation - 然后将所述语义描述为“一个荒谬的,复杂的规则”和“他从Common Lisp中复制过的最糟糕的事情之一” - 参见Common Lisp's reduce contract。演讲是关于传感器的,而这句话的背景是transduce的讨论,它有一个更优越,更简单的合同; r/reduce也可以。

  2. 即使不考虑上述情况,也很高兴reduce的版本与fold的合同非常接近。这样可以简化“尝试一个,尝试另一个”用相同的论点进行基准测试,以及简单地改变一个人的想法。