gpt4 book ai didi

clojure - 在 Clojure 中,惰性序列总是分块吗?

转载 作者:行者123 更新时间:2023-12-02 11:49:41 25 4
gpt4 key购买 nike

我的印象是惰性序列总是被分块。

=> (take 1 (map #(do (print \.) %) (range)))
(................................0)

正如预期的那样,打印了 32 个点,因为 range 返回的惰性序列被分成了 32 个元素 block 。但是,当我使用自己的函数 get-rss-feeds 而不是 range 尝试此操作时,惰性 seq 不再分块:

=> (take 1 (map #(do (print \.) %) (get-rss-feeds r)))
(."http://wholehealthsource.blogspot.com/feeds/posts/default")

只打印了一个点,所以我猜 get-rss-feeds 返回的惰性序列没有被分块。确实:

=> (chunked-seq? (seq (range)))
true

=> (chunked-seq? (seq (get-rss-feeds r)))
false

这是get-rss-feeds的来源:

(defn get-rss-feeds
"returns a lazy seq of urls of all feeds; takes an html-resource from the enlive library"
[hr]
(map #(:href (:attrs %))
(filter #(rss-feed? (:type (:attrs %))) (html/select hr [:link])))

因此, block 度似乎取决于惰性序列的生成方式。我查看了函数 range 的源代码,有迹象表明它是以“ block 状”方式实现的。所以我对它是如何工作的有点困惑。有人可以澄清一下吗?

<小时/>

这就是我需要知道的原因。

我必须遵循以下代码:(get-rss-entry (get-rss-feeds h-res) url)

get-rss-feeds 的调用返回我需要检查的提要 URL 的惰性序列。

get-rss-entry 的调用会查找特定条目(其 :link 字段与 get-rss-entry 的第二个参数匹配)。它检查 get-rss-feeds 返回的惰性序列。评估每个项目需要通过网络发出 http 请求来获取新的 rss feed。为了最大限度地减少 http 请求的数量,逐一检查序列并在匹配时立即停止非常重要。

这是代码:

(defn get-rss-entry
[feeds url]
(ffirst (drop-while empty? (map #(entry-with-url % url) feeds))))

entry-with-url 返回一个惰性匹配序列,如果没有匹配则返回一个空序列。

我对此进行了测试,它似乎工作正常(一次评估一个提要网址)。但我担心在某个地方,不知怎的,它会开始以一种“笨重”的方式表现,并且它会开始一次评估 32 个提要。我知道有办法 avoid chunky behavior as discussed here ,但在这种情况下似乎根本不需要。

我是否不惯用地使用惰性序列?循环/重复会是更好的选择吗?

最佳答案

你的担心是对的。如果 feeds 参数是一个返回分块 seqs 的集合,那么您的 get-rss-entry 确实会调用超出严格必要范围的 entry-with-url 。例如,如果 feeds 是一个向量,map 将一次对整个 block 进行操作。

这个问题在 Fogus 的《Joy of Clojure》中直接得到了解决,函数 seq1 在第 12 章中定义:

(defn seq1 [s]
(lazy-seq
(when-let [[x] (seq s)]
(cons x (seq1 (rest s))))))

您可以在调用 entry-with-url 之前,在您知道自己想要最懒的地方使用此方法:

(defn get-rss-entry  [feeds url]  (ffirst (drop-while empty? (map #(entry-with-url % url) (seq1 feeds)))))

关于clojure - 在 Clojure 中,惰性序列总是分块吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12412038/

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