Clojure website定义 reducer ,如下所示:
reducer是一个可简化的集合(一个知道如何减少自身的集合)与一个简化函数的组合("配方"在还原过程中需要做什么)。
以下是reducer
功能的实施(来自Rich' blog post on the topic)
(defn reducer
([coll xf]
(reify
clojure.core.protocols/CollReduce
(coll-reduce [_ f1 init]
(clojure.core.protocols/coll-reduce coll (xf f1) init)))))
似乎更准确地说减速器是可简化集合和减少函数变换器(后来称为transducer)的组合,而不是减少功能。
减速机不知道"有关减少功能的任何内容,由reduce
提供。它所知道的只是一个"配方"用于减少某些功能并修改(转换)它。
我的理解是否正确定义" reducer"?或者是否有一些关于"可还原收集的减少功能"定义
答案 0 :(得分:0)
文档中的语言混淆了减速器和传感器。换能器可以被认为只是减速器的优化实现,其目标是减少对象分配(和后续GC)。此优化不会更改减速器的概念模型。
因此,坚持使用普通的reduce
,其目标是简单地提供一种方法来累积序列的结果。最简单的例子是总计一个序列:
(ns clj.core
(:require [clojure.string :as str] )
(:use tupelo.core)) ; it->
(def values (range 6))
(spyx values)
(def total (reduce + 0 values))
(spyx total)
;=> values => (0 1 2 3 4 5)
;=> total => 15
然而,“减少功能”可以做任何事情。它也可以返回序列,而不仅仅是标量值:
(def duplicate (reduce (fn [cum-result new-val] ; accumulating function
(conj cum-result new-val))
[] ; initial value
values)) ; sequence to process
(spyx duplicate)
;=> duplicate => [0 1 2 3 4 5]
这是一个更复杂的缩减函数,它计算输入序列的积分:
(def integral (reduce (fn [cum-state new-val] ; accumulating function
(let [integ-val (+ (:running-total cum-state) new-val) ]
{ :integ-vals (conj (:integ-vals cum-state) integ-val)
:running-total integ-val} ))
{:integ-vals [] :running-total 0} ; initial value
values)) ; sequence to process
(spyx integral)
;=> integral => {:integ-vals [0 1 3 6 10 15], :running-total 15}
所以这与map
相比有很大的不同。我们将map
称为:
(def y (map f x))
其中x
和y
是序列,结果类似于
y(0) = f( x(0) ) ; math notation used here
y(1) = f( x(1) )
y(2) = f( x(2) )
...
因此每个y(i)仅依赖 函数f
和x(i)。相反,我们将reduce
定义为:
(def y(reduce f init x))
其中x
和y
是序列,init
是标量(如0
或[]
)。结果看起来像
y(0) = f( init, x(0) ) ; math notation used here
y(1) = f( y(0), x(1) )
y(2) = f( y(1), x(2) )
...
因此减少功能 f
是 2值的函数:累积结果和新的x
值。
答案 1 :(得分:0)
当您从博客中查看reducer
函数的来源时:
(defn reducer
([coll xf]
(reify
clojure.core.protocols/CollReduce
(coll-reduce [_ f1 init]
(clojure.core.protocols/coll-reduce coll (xf f1) init)))))
你可以看到reducer要求集合自行减少(通过调用coll上的coll-reduce
)并提供一个通过调用reduce函数变换器((xf f1)
)生成的reduce函数。 / p>
所以我会说这句话:
减速器是可减少集合和减少函数变换器(后来称为传感器)的组合,而不是减少函数。
更准确,因为你需要开始的是可简化的集合和还原函数转换器。减少函数只是调用reduce函数变换器的结果。