Clojure 在懒惰的seq上无休止地循环

Clojure 在懒惰的seq上无休止地循环,clojure,Clojure,为什么在Clojure中使用循环进行第二次评估是无止境的 user=> (->> (range) butlast lazy-seq (take 0)) () user=> (->> (range) butlast lazy-seq first) ; ... Haskell中的等价物可以合理地进行惰性评估 ghci> take 0 . init $ [0..] [] ghci> head . init $ [0..] 0 编辑 没有下文所指出的o

为什么在Clojure中使用循环进行第二次评估是无止境的

user=> (->> (range) butlast lazy-seq (take 0))
()
user=> (->> (range) butlast lazy-seq first) ; ...
Haskell中的等价物可以合理地进行惰性评估

ghci> take 0 . init $ [0..]
[]
ghci> head . init $ [0..]
0
编辑


没有下文所指出的op。

如果您查看
但最后一个
的实现,您可以看到它是急切的(使用
循环
而不是
惰性序列
)。另一种惰性实现可以满足您的需要:

(defn butlast'
  "Like clojure.core/butlast but lazy."
  [xs]
  (when (seq xs)
    ((fn f [[x & xs]]
       (if (seq xs)
         (lazy-seq (cons x (f xs)))
         ()))
     xs)))
为什么第二次评估在Clojure中无休止地循环

user=> (->> (range) butlast lazy-seq (take 0))
()
user=> (->> (range) butlast lazy-seq first) ; ...
butlast
是非惰性的,因为它枚举整个输入序列并建立一个新集合,直到耗尽输入

在这两个版本中,
butlast
消除了上游的惰性,因此我认为另一个相关的问题是“当涉及
butlast
时,为什么第一个版本会返回?”:
take 0
是一个不可操作的选项-当n不是正数时,它不会消耗输入序列,因此不管传递什么

另外,我认为Clojure代码与
head相当。尾部$[0..]
将是:

(->> (range) rest first) ;; => 1

butlast
与您想要的正好相反。

(>(范围)butlast'first)
是惰性评估,而不是
0
而不是
1
。从
tail
更正为
init
。无限序列的第二个最后一个元素是什么?Infinte序列只有下限。我想我们不能倒退。