gpt4 book ai didi

clojure - 如何正确使用LazySeq

转载 作者:行者123 更新时间:2023-12-01 16:40:03 26 4
gpt4 key购买 nike

我在使用lazySeq的时候有十几个困惑。

问题:

(def fib
(lazy-seq
(concat [0 1] (map + fib (rest fib))))) ;; It's Ok
(take 10 fib) ;; Bomb

收到错误消息:StackOverflowError clojure.lang.RT.more (RT.java:589)

以下解决方案效果很好:

(def fib
(concat [0 1] (lazy-seq (map + fib (rest fib))))) ;; Works well

(def fib
(lazy-cat [0 1] (map + fib (rest fib)))) ;; Works well

concatmap 都返回惰性序列,为什么上面的程序看起来很像,但又有所区别?

更详细地说,为什么第一个示例(lazy-seq 包装了 concat)失败了,但下面的示例(lazy-seq 包装了 map )成功了吗?

最佳答案

问题出在使用 rest在 map 操作中。基本上当你的惰性序列将调用表达式: (concat [0 1] (map + fib (rest fib)))要返回 ISeq 对象,rest将会发生对 fib 的调用(因为这是 map 的参数,它必须首先执行,然后传递给映射,并且映射是惰性的,但在我们达到惰性之前会调用其余)。 rest将尝试调用 more 在 fib 上是 LazySeq对象和更多将导致 fib 惰性 seq 获取下一个 ISeq,这再次涉及整个 concat 的执行涉及rest的操作如此继续下去,直到堆栈被吹走。

您需要使用不会立即在 fib 上调用 next 的内容,例如 drop :

(def fib
(lazy-seq
(concat [0 1] (map + fib (drop 1 fib)))))

此外,在其他情况下 lazy-seq在里面concat rest未执行,因为它被包装在 lazy-seq 内操作使整个表达式成为将来当请求下一个 ISeq 时调用的函数。

希望这能澄清问题。

关于clojure - 如何正确使用LazySeq,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16294811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com