在clojure中懒洋洋地构建

时间:2011-04-13 01:45:50

标签: clojure set lazy-evaluation

我已经开始学习clojure,但是我无法绕过某些概念。例如,我想要做的就是使用这个函数并将其转换为懒惰地调用get-origlabels。

(defn get-all-origlabels []
    (set (flatten (map get-origlabels (range *song-count*)))))

我的第一次尝试使用递归但是炸毁了堆栈(歌曲计数大约是10,000)。我无法弄清楚如何使用尾递归。

get-origlabels每次调用时都会返回一个集合,但值通常在调用之间重复。 get-origlabels函数实际上做的是读取一个文件(从0到 song-count -1的每个值的不同文件)并返回存储在其中的单词。

任何指针都将非常感谢!

谢谢! -Philip

3 个答案:

答案 0 :(得分:7)

您可以使用mapcat获得所需内容。我相信把它放到一个真正的Clojure集合中就会去除它,因为(take 10 (set (iterate inc 0)))试图在服用10之前实现整个集合的事实就证明了这一点。

(distinct (mapcat get-origlabels (range *song-count*)))

这会给你一个懒惰的序列。您可以通过执行类似的操作来验证:从无限序列开始:

(->> (iterate inc 0)
     (mapcat vector)
     (distinct)
     (take 10))

你最终会得到一个seq,而不是一套,但因为听起来你真的想在这里懒惰,我觉得这是最好的。

答案 1 :(得分:1)

这可能有更好的堆栈行为

(defn get-all-origlabels []
    (reduce (fn (s x) (union s (get-origlabels x))) ${} (range *song-count*)))

答案 2 :(得分:1)

我可能会使用类似的东西:

(into #{} (mapcat get-origlabels (range *song-count*)))

通常,在构造Clojure数据结构时,“into”非常有用。我有一个传送带(一个序列)的心理图像,将一堆随机物体放入一个大桶(目标集合)。