关于reduce:Clojure缩减功能

Clojure reduced function

我知道有reduced函数可以终止这种无限的事物,但是我很好奇为什么在第二个版本中(具有arg的range却没有终止),当达到150时,它不会终止还原吗?

1
2
3
user=> (reduce (fn [a v] (if (< a 100) (+ a v) a)) (range 2000))
105
user=> (reduce (fn [a v] (if (< a 100) (+ a v) a)) (range))

如您所提,对于后来出现的谷歌搜索者,请减少搜索范围。减少函数确实具有显式声明减少的最终答案的能力,并保证不会通过返回调用(reduced the-final-answer)的结果而消耗更多的输入

1
2
3
4
5
6
user> (reduce (fn [a v]
                (if (< a 100)
                  (+ a v)
                  (reduced a)))
               (range))
105

在这种情况下,当新收集的结果超过100时,下一次迭代将停止减少,而不是将其值用于答案。这确实会消耗输入流中未包含在结果中的一个额外值。

1
2
3
4
5
6
7
user> (reduce (fn [a v]
                (let [res (+ a v)]
                  (if (< res 100)
                    res
                    (reduced res))))
              (range))
105

只要达到阈值,就可以完成还原,并且不会消耗惰性(和无限)集合的任何额外值。


因为,减少将功能应用于序列(范围)中的每个元素,从而(范围)得以充分实现。

1
 (range)

产生无限序列,并且

1
 (fn [a v] (if (< a 100) (+ a v) a))

不会停止循环,而是将其应用于每个元素。

在REPL执行

1
 (reduce (fn [a v] (if (< a 100) (+ a v) a)) (range))

意味着我们很想获得并打印结果,因此REPL挂起。