Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
变压器和减速器的区别是什么Clojure_Clojure_Transform_Reducers - Fatal编程技术网

变压器和减速器的区别是什么Clojure

变压器和减速器的区别是什么Clojure,clojure,transform,reducers,Clojure,Transform,Reducers,从我收集的资料来看,transformer使用的是改变、改变元素集合的函数。就像我在一个 [1 2 3 4 5] 它变成了 [2 3 4 5 6] 但是为这个编写代码看起来像 (map inc) 但我一直把这种代码和减缩器混淆在一起。因为它产生了一个新的累积结果 我要问的问题是,变压器和减速器之间有什么区别?您可能只是混淆了各种术语(如上面的评论所示),但我会在解释减速器和变压器的含义时自由地回答您的问题 减少: reduce函数(您可能认为是reducer)是一个接受累积值和当前值并返回

从我收集的资料来看,transformer使用的是改变、改变元素集合的函数。就像我在一个

[1 2 3 4 5]
它变成了

[2 3 4 5 6]
但是为这个编写代码看起来像

(map inc)
但我一直把这种代码和减缩器混淆在一起。因为它产生了一个新的累积结果


我要问的问题是,变压器和减速器之间有什么区别?

您可能只是混淆了各种术语(如上面的评论所示),但我会在解释减速器和变压器的含义时自由地回答您的问题

减少:

reduce函数(您可能认为是reducer)是一个接受累积值和当前值并返回新累积值的函数

(accumulated, current) => accumulated
这些函数被传递到reduce,它们依次通过一个序列执行reduce函数体使用两个参数(累计和当前)所说的任何操作,然后返回一个新的累计值,该值将用作reduce函数下一次调用的累计值(第一个参数)

例如,plus可以被视为一个缩减函数

(reduce + [0 1 2]) => 3
首先,使用0和1调用reduce函数(本例中为plus),后者返回1。在下一次调用中,1现在是累积值,2是当前值,因此使用1和2调用plus,返回3,这就完成了缩减,因为集合中没有其他要处理的元素

查看reduce实现的简化版本可能会有所帮助:

(defn reduce1
  ([f coll] ;; f is a reducing function
      (let [[x y & xs] coll]
           ;; called with the accumulated value so far "x"
           ;; and cur value in input sequence "y"
           (if y (reduce1 f (cons (f x y) xs)) 
               x)))
  ([f start coll]
      (reduce1 f (cons start coll))))
您可以看到函数“f”或“reduction function”在每次迭代时都会被调用,其中包含两个参数,即到目前为止的累积值和输入序列中的下一个值。此函数的返回值用作下一次调用等的第一个参数,因此具有以下类型:

(x,y)=>x

转换:

我认为你的意思是,转换意味着输入的形状不会改变,而只是根据任意函数进行修改。这将是传递给map的函数,因为它们应用于每个元素,并构建相同形状的新集合,但该函数应用于每个元素

(map inc [0 1 2]) => '(1 2 3)
请注意,形状是相同的,它仍然是一个3元素序列,而在上面的简化中,输入一个3元素序列并返回一个整数。减少可以改变最终结果的形状,但贴图不会

请注意,我说的“形状”不会改变,但每个元素的类型可能会根据“变换”函数的作用而改变:

(map #(list (inc %)) [0 1 2]) => '((1) (2) (3))
它仍然是一个3个元素的序列,但现在每个元素都是一个列表,而不是一个整数

附录:

Clojure中有两个相关的概念,减速机和传感器,我只是想提一下,因为您询问了减速机(在Clojure中具有特定的含义)和转换器(这是Clojure法学家通常通过缩写“xf”指定给转换功能的名称)。如果我试着在这里解释这两个问题的细节,就会把这个已经很长的答案变成一个短篇故事,而且我做得比别人好:

传感器:

减速器和传感器:

事实证明,集合的许多转换都可以用reduce表示。例如,map可以实现为

(defn map [f coll] (reduce (fn [x y] (conj x (f y))) [] [0 1 2 3 4]))
然后你会打电话

(map inc [1 2 3 4 5])
取得

[2 3 4 5 6]
在我们自制的map实现中,我们传递给reduce的函数是

(fn [x y] (conj x (f y))))
其中f是我们希望应用于每个元素的函数。所以我们可以编写一个函数,为我们生成这样一个函数,传递我们想要映射的函数

(defn mapping-with-conj [f] (fn [x y] (conj x (f y))))
但是我们仍然可以在上面的函数中看到conj的存在,假设我们想向集合中添加元素。通过额外的间接操作,我们可以获得更大的灵活性:

(defn mapping [f] (fn [step] (fn [x y] (step x (f y)))))
然后我们可以这样使用它:

(def increase-by-1 (mapping inc))
(reduce (increase-by-1 conj) [] [1 2 3])
您所指的
(map inc)
实现了我们对
(mapping inc)
的调用。你为什么要这样做?答案是,它给了我们很多构建东西的灵活性。例如,我们可以不建立集合,而是

(reduce ((map inc) +) 0 [1 2 3 4 5])
这将为我们提供映射集合的总和[2 3 4 5 6]。或者,我们可以通过简单的函数组合添加额外的处理步骤

(reduce ((comp (filter odd?) (map inc)) conj) [] [1 2 3 4 5])
这将首先从集合中删除偶数元素,然后再映射。Clojure中的
transduce
函数基本上完成了上面一行所做的工作,但也处理了其他一些额外的细节。你真的会写

(transduce (comp (filter odd?) (map inc)) conj [] [1 2 3 4 5])

总之,Clojure中的
map
函数有两个算术数。像
(map inc[1 2 3 4 5])
那样调用它将映射集合中的每个元素,以便获得
[2 3 4 5 6]
。就像
(map inc)
一样调用它,给我们提供了一个功能,其行为与上述解释中的
映射
功能非常相似。

您混淆了
(map inc)
?可能是您混淆了传感器和变压器吗?据我所知,变压器在Clojure中不是一个技术术语。我相信在传感器功能的早期迭代中称为“减少功能变压器”的传感器,但仅此而已。很久以前,hiredman写过一篇文章,解释了减缩器以及它们是如何转化的,我发现这很有用。