(上面的命令计算用户名中大写或小写字母 r 的用户数)。这是作为一组进程实现的,每个进程都从前一个进程的输出中读取,因此有四个中间流。您可以想象一个不同的实现,它将这五个命令组合成一个单独的聚合命令,这个聚合命令从它的输入读取并写入它的输出。如果中间流是昂贵的,而且成分是便宜的,这可能是一个很好的权衡。
Transducers are a powerful and composable way to build algorithmic transformations that you can reuse in many contexts, and they’re coming to Clojure core and core.async.
;; Example 1a - using a reducer to add up all the mapped values
(def ex1a-map-children-to-value-1 (r/map #(if (= :child (:role %)) 1 0)))
(r/reduce + 0 (ex1a-map-children-to-value-1 village))
;;=>
8
下面是另一种方法:
;; Example 1b - using a transducer to add up all the mapped values
;; create the transducers using the new arity for map that
;; takes just the function, no collection
(def ex1b-map-children-to-value-1 (map #(if (= :child (:role %)) 1 0)))
;; now use transduce (c.f r/reduce) with the transducer to get the answer
(transduce ex1b-map-children-to-value-1 + 0 village)
;;=>
8
此外,它在考虑子组时也非常强大。例如,如果我们想知道布朗家庭有多少孩子,我们可以执行:
;; Example 2a - using a reducer to count the children in the Brown family
;; create the reducer to select members of the Brown family
(def ex2a-select-brown-family (r/filter #(= "brown" (string/lower-case (:family %)))))
;; compose a composite function to select the Brown family and map children to 1
(def ex2a-count-brown-family-children (comp ex1a-map-children-to-value-1 ex2a-select-brown-family))
;; reduce to add up all the Brown children
(r/reduce + 0 (ex2a-count-brown-family-children village))
;;=>
2
A mapping function is just one of a class of functions that are sometimes referred to as "reducing functions". Another common reducing function is filter which remove values that match a predicate (e.g. remove all values that are even).
As far as I understand, they're like 积木, decoupled from the input and output implementation. You just define the operation.
As the implementation of the operation is not in the input's code and nothing is done with the output, transducers are extremely reusable. They remind me of 流动s in 阿卡溪流.
I'm also new to transducers, sorry for the possibly-unclear answer.