Clojure 在懒惰的seq上无休止地循环
为什么在Clojure中使用循环进行第二次评估是无止境的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
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序列只有下限。我想我们不能倒退。