在 Clojure 中延迟构建集
我已经开始学习 clojure,但我很难理解某些概念。例如,我在这里想要做的是获取此函数并将其转换,以便它延迟调用 get-origlabels。
(defn get-all-origlabels []
(set (flatten (map get-origlabels (range *song-count*)))))
我的第一次尝试使用了递归,但炸毁了堆栈(song-count 约为 10,000)。我不知道如何用尾递归来做到这一点。
get-origlabels 每次调用时都会返回一个集合,但值通常在调用之间重复。 get-origlabels 函数实际上的作用是读取一个文件(从 0 到 song-count-1 的每个值都有一个不同的文件)并返回存储在其中的单词集合。
任何指示将不胜感激!
谢谢! -菲利普
I've started to learn clojure but I'm having trouble wrapping my mind around certain concepts. For instance, what I want to do here is to take this function and convert it so that it calls get-origlabels lazily.
(defn get-all-origlabels []
(set (flatten (map get-origlabels (range *song-count*)))))
My first attempt used recursion but blew up the stack (song-count is about 10,000). I couldn't figure out how to do it with tail recursion.
get-origlabels returns a set each time it is called, but values are often repeated between calls. What the get-origlabels function actually does is read a file (a different file for each value from 0 to song-count-1) and return the words stored in it in a set.
Any pointers would be greatly appreciated!
Thanks!
-Philip
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你可以使用
mapcat
得到你想要的东西。我相信将它放入实际的 Clojure 集合中将会消除它的惰性,正如(take 10 (set (iterate inc 0)))
尝试在 take 之前实现整个集合的事实所证明的那样10.这会给你一个惰性序列。您可以通过执行类似的操作来验证这一点,从无限序列开始:
您最终会得到一个 seq,而不是一个集合,但由于听起来您确实想要在这里懒惰,所以我认为这是最好的。
You can get what you want by using
mapcat
. I believe putting it into an actual Clojure set is going to de-lazify it, as demonstrated by the fact that(take 10 (set (iterate inc 0)))
tries to realize the whole set before taking 10.This will give you a lazy sequence. You can verify that by doing something like, starting with an infinite sequence:
You'll end up with a seq, rather than a set, but since it sounds like you really want laziness here, I think that's for the best.
这可能有更好的堆栈行为
This may have better stack behavior
我可能会使用类似的东西:
一般来说,“into”在构建 Clojure 数据结构时非常有用。我的脑海中浮现出这样的画面:传送带(一个序列)将一堆随机物体放入一个大桶(目标集合)中。
I'd probably use something like:
In general, "into" is very helpful when constructing Clojure data structures. I have this mental image of a conveyor belt (a sequence) dropping a bunch of random objects into a large bucket (the target collection).