Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何编写一个谓词来检查无限序列中是否存在值?_Clojure_Predicate_Lazy Sequences - Fatal编程技术网

Clojure 如何编写一个谓词来检查无限序列中是否存在值?

Clojure 如何编写一个谓词来检查无限序列中是否存在值?,clojure,predicate,lazy-sequences,Clojure,Predicate,Lazy Sequences,今天我有了一个关于高阶函数的想法,我不知道如何编写。我有几个稀疏的、惰性的无限序列,我想创建一个抽象,让我检查给定的数字是否在这些惰性序列中。为了提高性能,我想将稀疏序列的值推送到hashmap(或set)中,在必要时动态增加hashmap中的值数量。由于懒惰seq的稀疏性,自动记忆不是这里的答案 也许代码是最容易理解的,所以这里是我到目前为止所拥有的。如何更改以下代码,使谓词使用闭合的hashmap,但如果需要,则增加hashmap的大小并重新定义自身以使用新的hashmap (defn ma

今天我有了一个关于高阶函数的想法,我不知道如何编写。我有几个稀疏的、惰性的无限序列,我想创建一个抽象,让我检查给定的数字是否在这些惰性序列中。为了提高性能,我想将稀疏序列的值推送到hashmap(或set)中,在必要时动态增加hashmap中的值数量。由于懒惰seq的稀疏性,自动记忆不是这里的答案

也许代码是最容易理解的,所以这里是我到目前为止所拥有的。如何更改以下代码,使谓词使用闭合的hashmap,但如果需要,则增加hashmap的大小并重新定义自身以使用新的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))))

如何在不恢复命令式风格的情况下解决此问题?

此函数基于核心记忆功能的工作原理。只有已从延迟列表中使用的数字才会缓存在集合中。它使用内置的take while,而不是手动执行搜索

(defn make-lazy-predicate [coll]
  (let [mem (atom #{})
        unknown (atom coll)]
    (fn [item]
      (if (< item (first @unknown))
        (@mem item)
        (let [just-checked (take-while #(>= item %) @unknown)]
          (swap! mem #(apply conj % just-checked))
          (swap! unknown #(drop (count just-checked) %))
          (= item (last just-checked)))))))
(defn使惰性谓词[coll]
(let[mem(atom{})
未知(原子coll)]
(fn[项目]
(如果(<项目(第一个@未知))
(@mem项目)
(让[刚刚选中(花点时间,#(>=项目%@未知)]
(swap!mem#(应用刚刚选中的百分比))
(交换!未知#(丢弃(刚刚检查计数)%)
(=项目(上一次刚勾选的项目)

这是Adam解决方案的线程安全变体

(defn make-lazy-predicate
  [coll]
  (let [state        (atom {:mem #{} :unknown coll})
        update-state (fn [{:keys [mem unknown] :as state} item]
                       (let [[just-checked remainder]
                             (split-with #(<= % item) unknown)]
                         (if (seq just-checked)
                           (-> state
                             (assoc :mem (apply conj mem just-checked))
                             (assoc :unknown remainder))
                           state)))]
    (fn [item]
      (get-in (if (< item (first (:unknown @state)))
                @state
                (swap! state update-state item))
              [:mem item]))))
(defn使惰性谓词
[coll]
(let[态(原子{:mem{}:未知coll})
更新状态(fn[{:keys[mem未知]:as state}项]
(让[[刚刚选中的余数]
(与#分开)(州)
(助理:mem(应用刚刚选中的conj mem))
(助理:未知余数))
[国家])]
(fn[项目]
(进入(如果(

你也可以考虑使用REFS,但是你的谓词搜索可能会被封闭的事务回滚。这可能是也可能不是你想要的。

我发现在概念上很难证明一个值不包含在一个无限的序列中。谢谢亚当!阅读你的解决方案首先帮助我了解kotarak的改进。太好了!我猜我必须用原子来保持状态的变化,但不确定如何实现。我喜欢在这里用拆分、解构和进入做了多少工作。谢谢!