使用recur、lazy seq的Clojure堆栈溢出?
我读过其他人关于Clojure中存在堆栈溢出问题的问题,而这个问题往往是在某个地方建立的惰性序列。这似乎是这里的问题,但就我的一生而言,我不知道在哪里 下面是代码,代码之后是一些解释:使用recur、lazy seq的Clojure堆栈溢出?,clojure,overflow,lazy-evaluation,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
(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))))
这仍然以java.lang.StackOverflowError(repl-1:331)结束。堆栈跟踪对我来说没有什么意义,只是它确实似乎表明了正在发生的懒惰序列混乱。还有什么建议吗?我是否需要将代码发布到处理歌曲调用的函数中?谢谢 如果没有更具体的示例数据,我无法完全理解您要做什么,但很明显,您正试图使用递归对数据进行迭代。你让事情变得比你需要的更痛苦 如果您可以生成一个函数,让我们调用它dothething,它在地图中的一个条目中正确运行,那么您可以调用(map dothething(counted origlabel)),它将应用(dothething)到(counted origlabel)中的每个地图条目,将单个映射项作为惟一参数传递给dothing,并从dothing返回一系列返回值 看起来还需要索引,这也很容易解决。您可以将惰性序列(范围)拼接为第二个参数来执行此操作,然后您将使用每个映射项生成一系列索引;但是clojure中的贴图默认情况下不会排序,因此除非您使用的是已排序的贴图,否则该索引值相对来说没有意义 要想抽象出您目前所写的内容,请尝试以下方法:
(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)))
嗨,谢谢你的回复。我认为我无法生成一个函数,该函数只需从映射中输入一个条目即可正确运行。“pare keywords”函数需要映射的所有条目,其键包含在序列“o”和“g”中。此外,虽然使用索引调用pare关键字的顺序并不重要,但重要的是每次调用都要更新映射,以便后续调用具有更新的版本。所以我可以这样做来克服前一个问题,但不是后一个问题,对吗?哦,点击return:(map(partial do the thing counted origlabels)…)?仔细检查,我不确定我是否理解(constantive(counted origlabels))部分的功能。我对constantive(constantive)(counted origlabels))的用法大错特错,应该使用(repeat(repeat(counted origlabels)). 不断返回一个函数,该函数不断返回您给它的值。重复旋转一个无限序列,其中每个元素都是你给它的值。通过使用(重复(计数的Origlabel),您将在每次调用中始终拥有完整的映射。在没有更多上下文的情况下,很难尝试和理解您正在执行的操作,但您似乎希望为映射中的每个值向磁盘写入一些值。您还希望根据某些条件潜在地更改映射中的每个值。首先,将这些问题解耦t不要将条件更改应用于原始映射中的每个值以生成新映射。然后将新映射中的适当值写入磁盘。我理解,做出这些关于以完全不同的方式做事的断言似乎没有多大帮助。我认为,如果您尝试这些断言,您可能会真正享受结果。
(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)))