2012-07-08 57 views
5

Clojure的功能为什么不是仅仅由惰性函数调用组成的Clojure函数呢?

(reductions + 0 (cycle [1 1 -1])) 

产生序列[0 1 2 1 2 3 2 3 4 3 4 5 ...]。不幸的是,这个序列不是懒惰的。

由于cyclereductions都被记录为返回惰性序列,我预计这些函数的这些组合也会返回一个惰性序列。为什么不呢,我该如何修复它以便懒惰地返回序列?

更复杂的例子,显示了同样的问题:

(reductions (fn [x f] (f x)) 0 (cycle [inc inc dec])) 

(我证明这一点,因为这是我想在结束了工作的版样,万一有什么差别)

回答

9

不幸的是,这个序列不是懒惰的。

哦,是的,它是。我们可以快速检查,这是懒惰利用其前10个元素:

(take 10 (reductions + 0 (cycle [1 1 -1]))) 

这很快会返回一个答案,证明了该序列是懒惰。如果函数不是懒惰的,它会试图实现无限序列中的所有元素,并且会打击内存,或者陷入无限循环。

会发生什么是你在REPL中输入这个func,它试图在显示给你之前实现序列。

编辑:如果您发现您触发了一个或意外尝试实现无限次序,请使用此提示至stop infinite loops

+0

谢谢:)。我试图通过(def ...)声明来消除序列,以防止这种情况发生,但是当然(现在我意识到)这是行不通的。用(defn ...)命名它工作得很好。 – Confusion 2012-07-09 05:37:40

+1

更准确的方法来检查一个函数是否懒惰包装它实现? 。如果返回false,则该函数是懒惰的。 =>(实现了?(减少+0(周期[1 1 -1]))) false – NielsK 2012-07-09 08:46:22

+1

'实现?'对于这个目的非常不利(实际上,对于大多数目的而言,希望它很快得到改进)。在所有这些值上尝试'实现':'''''','nil',''(a b c)','(iterate inc 0)',你会明白我的意思。 – amalloy 2012-07-09 18:28:15

相关问题