如何编写一个谓词来检查无限序列中是否存在某个值?
今天我有一个高阶函数的想法,但我不知道如何编写。我有几个稀疏的、惰性的无限序列,我想创建一个抽象,让我检查给定的数字是否在这些惰性序列中。为了提高性能,我想将稀疏序列的值推送到哈希映射(或集合)中,并在必要时动态增加哈希映射中的值的数量。由于惰性序列的稀疏性,自动记忆并不是这里的答案。
代码可能是最容易理解的,所以这就是我到目前为止所拥有的。如何更改以下代码,以便谓词使用封闭的哈希图,但如果需要,则增加哈希图的大小并重新定义自身以使用新的哈希图?
(defn make-lazy-predicate [coll]
"Returns a predicate that returns true or false if a number is in
coll. Coll must be an ordered, increasing lazy seq of numbers."
(let [in-lazy-list? (fn [n coll top cache]
(if (> top n)
(not (nil? (cache n)))
(recur n (next coll) (first coll)
(conj cache (first coll)))]
(fn [n] (in-lazy-list? n coll (first coll) (sorted-set)))))
(def my-lazy-list (iterate #(+ % 100) 1))
(let [in-my-list? (make-lazy-predicate my-lazy-list)]
(doall (filter in-my-list? (range 10000))))
如何在不恢复命令式风格的情况下解决这个问题?
I had an idea for a higher-order function today that I'm not sure how to write. I have several sparse, lazy infinite sequences, and I want to create an abstraction that lets me check to see if a given number is in any of these lazy sequences. To improve performance, I wanted to push the values of the sparse sequence into a hashmap (or set), dynamically increasing the number of values in the hashmap whenever it is necessary. Automatic memoization is not the answer here due to sparsity of the lazy seqs.
Probably code is easiest to understand, so here's what I have so far. How do I change the following code so that the predicate uses a closed-over hashmap, but if needed increases the size of the hashmap and redefines itself to use the new hashmap?
(defn make-lazy-predicate [coll]
"Returns a predicate that returns true or false if a number is in
coll. Coll must be an ordered, increasing lazy seq of numbers."
(let [in-lazy-list? (fn [n coll top cache]
(if (> top n)
(not (nil? (cache n)))
(recur n (next coll) (first coll)
(conj cache (first coll)))]
(fn [n] (in-lazy-list? n coll (first coll) (sorted-set)))))
(def my-lazy-list (iterate #(+ % 100) 1))
(let [in-my-list? (make-lazy-predicate my-lazy-list)]
(doall (filter in-my-list? (range 10000))))
How do I solve this problem without reverting to an imperative style?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是 Adam 解决方案的线程安全变体。
人们也可以考虑使用 refs,但是您的谓词搜索可能会被封闭的事务回滚。这可能是也可能不是您想要的。
This is a thread-safe variant of Adam's solution.
One could also consider using refs, but than your predicate search might get rolled back by an enclosing transaction. This might or might not be what you want.
该函数基于核心 memoize 函数的工作原理。只有已经从惰性列表中消耗的数字才会被缓存在集合中。它使用内置的 take-while 而不是手动进行搜索。
This function is based on the idea how the core memoize function works. Only numbers already consumed from the lazy list are cached in a set. It uses the built-in take-while instead of doing the search manually.