Clojure 堆栈溢出使用 recur、lazy seq?

标签 clojure overflow lazy-evaluation

我读过其他人关于在 Clojure 中遇到堆栈溢出问题的问题,问题往往是在某处建立了一个懒惰的序列。这似乎是这里的问题,但对于我的生活,我不知道在哪里。

这是代码,代码之后是一些解释:

(defn pare-all []
  "writes to disk, return new counts map"
(loop [counts (counted-origlabels)
     songindex 0]
(let [[o g] (orig-gen-pair songindex)]
  (if (< songindex *song-count*) ;if we are not done processing list
    (if-not (seq o) ;if there are no original labels
      (do
        (write-newlabels songindex g);then use the generated ones
        (recur counts (inc songindex)))
      (let [{labels :labels new-counts :countmap} (pare-keywords o g counts)] ;else pare the pairs
        (write-newlabels songindex labels)
        (recur new-counts (inc songindex))))
    counts))))

在最初从函数“counted-origlabels”中检索的“counts”中存储了一张 map 。该 map 具有字符串键和整数值。它大约有 600 个项目,并且在迭代过程中更新了值,但长度保持不变,我已经验证了这一点。

“orig-gen-pair”函数从一个文件中读取并返回一对短序列,每个序列有 10 个左右的项目。

“write-newlabels”函数只是将传递的序列写入磁盘,没有任何其他副作用,也不返回值。

“Pare-keywords”返回一个短序列和“counts”映射的更新版本。

我只是不明白是什么懒惰的序列可能会导致这里的问题!

任何提示将不胜感激!

- - 编辑 - -

大家好,我已经将我的函数更新为(希望)更惯用的 Clojure。但我原来的问题仍然存在。首先,这是新代码:
(defn process-song [counts songindex]
  (let [[o g] (orig-gen-pair songindex)]
(if-not (seq o) ;;if no original labels
  (do
    (write-newlabels songindex g);then use the generated ones
    counts)
  (let [{labels :labels new-counts :countmap} (pare-keywords o g counts)] ;else pare the pairs
    (write-newlabels songindex labels)
    new-counts))))

(defn pare-all []
  (reduce process-song (counted-origlabels) (range *song-count*)))

这仍然以 java.lang.StackOverflowError (repl-1:331) 结束。堆栈跟踪对我来说没有多大意义,除了它确实似乎表明正在进行的惰性序列困惑。还有什么提示吗?我是否需要将代码发布到处理歌曲调用的函数中?谢谢!

最佳答案

如果没有更具体的示例数据,我无法完全理解您要做什么,但是很明显您正在尝试使用递归遍历数据。你让事情变得比你需要的更痛苦。

如果您可以生成一个函数,让我们称其为 do-the-thing,它可以在您的 map 中使用单个条目正确运行,然后您可以调用 (map do-the-thing (counted-origlabels)),它将适用( do-the-thing) 到 (counted-origlabels) 中的每个映射条目,将单个映射条目传递给 do-the-thing 作为它的唯一参数,并从 do-the-thing 返回一系列返回值。

您看起来也需要索引,这也很容易解决。您可以将惰性序列(范围)拼接为 do-the-thing 的第二个参数,然后您将使用每个映射条目生成一系列索引;但是clojure中的maps默认是没有排序的,所以除非你使用的是排序好的map,否则这个索引值是相对没​​有意义的。

试图抽象出您到目前为止所写的内容,请尝试以下操作:

(defn do-the-thing [entry index counts]
  (let [[o g] (orig-gen-pair index)]
    (if-not (seq o)
      (write-newlabels index g)
      (let [{labels :labels new-counts :countmap} (pare-keywords o g counts)]
        (write-newlabels index labels)))))

(map do-the-thing (counted-origlabels) (range) (constantly (counted-origlabels)))

关于Clojure 堆栈溢出使用 recur、lazy seq?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5682326/

相关文章:

css - 使用 Clojure Hiccup 呈现样式信息的惯用方式

clojure - 请帮助我理解这些 Clojure Hprof 痕迹

loops - 在 Haskell 中融合多重折叠

haskell - 我的 Haskell 程序太懒了

Python 惰性求值器

clojure - 无法在 Clojure 中定义类?

clojure - Clojure 1.5 中的非用户命名空间中缺少文档

css - 更改 HTML 溢出

css - 侧面菜单页脚溢出

css - 负绝对定位,去除滚动条