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/ssh/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 - Fatal编程技术网

在Clojure中使序列副作用完全

在Clojure中使序列副作用完全,clojure,Clojure,我想做的是如下 (def mystream (stream (range 100))) (take 3 mystream) ;=> (0 1 2) (take 3 mystream) ;=> (3 4 5) (first (drop 1 mystream)) ;=> 7 流函数使序列副作用像io流一样完整。 我认为这几乎是不可能的。 这是我的尝试 (defprotocol Stream (first! [this])) (defn stream [lst] (le

我想做的是如下

(def mystream (stream (range 100)))

(take 3 mystream)
;=> (0 1 2)

(take 3 mystream)
;=> (3 4 5)

(first (drop 1 mystream))
;=> 7
流函数使序列副作用像io流一样完整。
我认为这几乎是不可能的。 这是我的尝试

(defprotocol Stream (first! [this]))

(defn stream [lst]
  (let [alst (atom lst)]
    (reify Stream
       (first! [this]
         (let [[fs] @alst]
           (swap! alst rest)
           fs)))))

(let [mystream (stream (iterate inc 1))]
  (map #(if (string? %) (first! mystream) %)
       [:a "e" "b" :c "i" :f]))
;=> (:a 1 2 :c 3 :f)

非同寻常的是,这种方法需要实现我将使用的所有功能。

这不适用于标准的take-and-drop,但您可以很容易地编写自己的代码来处理可变的atom,例如,您可以这样做:

(def mystream (atom (range 100)))

(defn my-take [n stream]
  (let [data @stream
        result (take n data)]
    (reset! stream (drop n data))
    result))  

(my-take 3 mystream)
=> (0 1 2)

(my-take 3 mystream)
=> (3 4 5)

从你对Maurits的后续评论来看,你不需要突变,只需要在正确的位置发射一个新的序列

例如:

(defn replace-when [pred coll replacements] (lazy-seq (when (seq coll) (if (seq replacements) (if (pred (first coll)) (cons (first replacements) (replace-when pred (rest coll) (rest replacements))) (cons (first coll) (replace-when pred (rest coll) replacements))) coll)))) (在[pred coll更换]时进行defn更换) (续) (何时(序号coll) (如有)(以下替换) (如果(前(第一列)) (反对(首次替换) (当pred(rest coll)(rest替换)时替换) (反对(第一coll) (更换pred(rest coll)时更换) coll)) 用户=>(定义顺序1[:a:b:c]) #'用户/seq1 用户=>(定义序列2[:x“i”“u”:y:z“e”]) #'用户/seq2 用户=>(当字符串为?seq2 seq1时替换) (:x:a:b:y:z:c)
这只是一个理论练习,还是你在试图解决一个真正的问题?在后一种情况下,可能会有更好的解决方案,当然这取决于您的问题。也许你可以详细解释一下。嗨。我正在努力为我的小项目解决真正的问题。我需要将sequnce1插入sequnce2中的字符串位置。例如,seq1:(:a:b:c),seq2:(:x“i”“u”:y:z“e”)=>(:x:a:b:y:z:c)。这可以通过以上我的尝试来实现,但我想推广它。我更喜欢在什么时候替换我的变异方法。非常感谢。 user=> (def seq1 [:a :b :c]) #'user/seq1 user=> (def seq2 [:x "i" "u" :y :z "e"]) #'user/seq2 user=> (replace-when string? seq2 seq1) (:x :a :b :y :z :c)