有什么区别:
(transduce (comp fn-1 fn-2 fn-3) conj vector-collection)
和
(eduction fn-1 fn-2 fn-3 vector-collection)
我已经阅读了教育文档,但不理解教育的目的。
有什么区别:
(transduce (comp fn-1 fn-2 fn-3) conj vector-collection)
和
(eduction fn-1 fn-2 fn-3 vector-collection)
我已经阅读了教育文档,但不理解教育的目的。
transduce
通过将归约函数应用于集合来归约转换器。计算结果。
eduction
只是记住您想将传感器应用于集合的东西。Eduction 本身并不是“常规意义上的”集合,而是实现了它的接口。因此,当您尝试打印它时,它会像顺序一样打印自己。
看这里:
(defn my-tran [rf]
(fn
([]
(println "Arity 0!")
(rf))
([res]
(println "Arity 1!")
(rf res))
([result input]
(println "Arity 2!")
(rf result input))))
> (def a (transduce my-tran conj '(1 2 3)))
Arity 2!
Arity 2!
Arity 2!
Arity 1!
#'test.core/a ;a is already finished
> (def r (eduction my-tran '(1 2 3)))
#'test.core/r ;nothing was done
> r
Arity 2!
Arity 2!
Arity 2!
Arity 1!
(1 2 3) ;now it's done. Next call with calculate it again. Check it.
> (sequential? r)
true
eduction
将转换器部分应用于没有归约函数的集合也是如此。但事实并非如此lazy-seq
。因此,当您transduce
或reduce
超过eduction
它时(在此时完成相同的工作,而不是在结果的意义上),就好像您transduce
使用归约函数调用原始集合一样。
请参阅: Clojure 转换器行为,其中有一个特殊的答案,涵盖了有关此想法的许多问题。
只是为了向@JustAnotherCurious 的精彩解释添加一个用于教育的用例。
Aneduction
允许您将一个或多个换能器与要转换的集合捆绑在一起,成为可以reduce
d 的东西,但eduction
不执行任何转换。
transduce
相反,实际上减少了集合,使用指定的转换器和减少函数。
我使用代码中的推导来创建或了解转换器和某些操作的集合,但需要对归约函数保持不可知论。所以我可以将推导的结果作为一个单元传递,并在某个已知归约函数可以归约它的地方使用它。
这可以帮助你保持你的方面分离(更多正交代码)并导致更清晰的代码。