为什么recur
中的这个mapcat
不终止,而命名的fn
调用版本等效呢?
(def tree [1 [2 [3 5]] [6 [[1 2] [8 [9 10]]]]])
(defn leaves
[node]
(mapcat #(if (vector? %) (leaves %) [%]) node))
(leaves tree)
;; => (1 2 3 5 6 1 2 8 9 10)
(defn leaves-with-recur
[node]
(mapcat #(if (vector? %) (recur %) [%]) node))
(leaves-with-recur tree)
;; Never terminates
如果对
recur
的这种使用是直截了当的禁止,那么是否有任何原因导致Clojure编译器不应该捕获这种情况并警告程序员,甚至拒绝对其进行编译?例如,对于recur
的非尾位置调用,情况就是如此。 最佳答案
#(if (vector? %) (recur %) [%])
是的简写
(fn [%]
(if (vector? %)
(recur %)
[%]))
该
recur
将递归到该匿名函数,而不是任何外部函数,并且由于它没有任何改变,因此这是一个无休止的循环。至于警告-停顿问题是无法解决的,并且即使在尝试实现一些启发式方法时,也有可能在编译时陷入无限循环的风险。
关于recursion - 为什么在mapcat中这种重复出现不终止?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52580006/