在clojure中懒洋洋地构建集
我已经开始学习clojure了,但是我在思考某些概念时遇到了困难。例如,我想在这里做的是将这个函数转换成get origlabels在clojure中懒洋洋地构建集,clojure,set,lazy-evaluation,Clojure,Set,Lazy Evaluation,我已经开始学习clojure了,但是我在思考某些概念时遇到了困难。例如,我想在这里做的是将这个函数转换成get origlabels (defn get-all-origlabels [] (set (flatten (map get-origlabels (range *song-count*))))) 我的第一次尝试使用递归,但却破坏了堆栈(歌曲数约为10000首)。我不知道如何使用尾部递归来实现它 get origlabels在每次调用时都返回一个集合,但值通常在调用之间重复。g
(defn get-all-origlabels []
(set (flatten (map get-origlabels (range *song-count*)))))
我的第一次尝试使用递归,但却破坏了堆栈(歌曲数约为10000首)。我不知道如何使用尾部递归来实现它
get origlabels在每次调用时都返回一个集合,但值通常在调用之间重复。get origlabels函数实际做的是读取一个文件(从0到song-count-1的每个值都有一个不同的文件),并以集合的形式返回其中存储的单词
任何指点都将不胜感激
谢谢!
-Philip这可能具有更好的堆栈行为
(defn get-all-origlabels []
(reduce (fn (s x) (union s (get-origlabels x))) ${} (range *song-count*)))
您可以使用
mapcat
获取所需内容。我相信把它放到一个实际的Clojure集合中会使它去懒惰,这一点可以从以下事实中得到证明:(取10(set(iterate inc 0))
在取10之前尝试实现整个集合
(distinct (mapcat get-origlabels (range *song-count*)))
这将为您提供一个惰性序列。您可以通过执行以下操作来验证,从无限序列开始:
(->> (iterate inc 0)
(mapcat vector)
(distinct)
(take 10))
你最终会得到一个seq,而不是一个set,但因为听起来你真的想要懒惰,我认为这是最好的选择。我可能会使用类似于:
(into #{} (mapcat get-origlabels (range *song-count*)))
通常,“into”在构造Clojure数据结构时非常有用。我脑海中有一幅传送带(一个序列)将一堆随机物体扔进一个大水桶(目标集合)的画面。+1用于解释设置“去惰性”序列。现在我们迫切需要一个动词来表达这一点。“认识到”这个顺序是这个的标准动词;我似乎懒得回忆它:)(iterate inc 0)与(range)相同,因此可以稍微缩短它。你也可以说懒惰的反面是“渴望”。set函数是渴望。