2017-05-05 55 views
3

我只是试图向别人展示懒惰,并且我编写了一个简单的递归函数来处理列表。在Clojure中,我如何编写自己的递归函数来处理懒惰列表?

我认为这将是一个无限大名单上的罚款。但是突然间我发现了一个“太多递归”的内部错误。

咦?我总是编写这样的代码。有什么问题?

当然不过,通常我使用像map内置功能的其他列表处理功能的基础。这次我试图编写自己的递归遍历。当然,这不可能奏效。

这是我写的。

(defn q [xs] 
    (if (empty? xs)() 
    (cons (* (first xs) (first xs)) (q (rest xs))))) 

(take 10 (q (cycle '(1 2 3 4)))) 

那么,事实上,我怎么写我自己的遍历函数,可以处理Clojure中的惰性数据结构呢?是否有某种类似的“收益”?

+0

见https://clojuredocs.org/clojure.core/lazy-seq –

回答

6
(defn q [xs] 
    (if (empty? xs)() 
    (lazy-seq ;; <- here's our magic! 
     (cons (* (first xs) (first xs)) (q (rest xs)))))) 

(take 10 (q (cycle '(1 2 3 4)))) 
+3

好,但应该是'(DEFN Q [XS](懒惰-SEQ(如果...)))',所以来自输入序列的项目仅在需要来自输出序列的项目时才实现。正如所写的,您总是会从输入序列中消耗比需要的更多的项目。作为一个经验法则,当你产生一个懒惰的序列时,你应该确保'lazy-seq'环绕着任何强制输入元素的东西(比如seq,first,rest或empty?)。 – amalloy