'重复'在Core.Async

时间:2017-03-05 19:27:16

标签: clojure core.async

请考虑以下代码段:

(require '[clojure.core.async :refer :all])


(def my-chan (chan (buffer 10)))

(go (while true
      (>! my-chan (rand))))

这基本上提供了一个缓冲通道,它总是包含大约10个随机数。消耗通道后,缓冲区将再次填充。

core.async中是否有这样的抽象?由于存在用于操纵通道消耗的换能器,因此也可能存在用于生产它们的东西:

对于序列,人们会选择这样的东西:

(def my-seq 
  (map (fn [_] (rand)) (range)))

或者,只是:

(def my-seq (repeatedly rand))

当然没有缓冲,但它可能会让我知道我在寻找什么。

1 个答案:

答案 0 :(得分:0)

传感器不会操纵频道消费 - 它们会影响价值,但它们不会影响频道数据的消费。

您似乎想要一种方法来抽象通道的创建,然后将其作为序列从中获取值。这里有一些想法,虽然我不相信core.async在这种情况下确实提供了高于普通clojure.core功能的任何东西。

抽象是按照通常的方式完成的 - 使用函数。这将调用f并将其结果放在频道上。这里的含义当然是f会产生副作用,而且不纯,否则从每个价值相同的角度来看,这将是一个非常无聊的渠道。

(defn chan-factory
  [f buf]
  (let [c (chan buf)]
    (go-loop []
      (>! c (f))
      (recur))
    c))

如果你想从中创建一个懒惰的序列,你可以这样做:

(defn chan-to-seq [c]
  (lazy-seq
    (cons (<!! c) (chan-to-seq c))))

定义你的seq:

(def rand-from-chan (chan-to-seq (chan-factory rand 10)))

(take 5 rand-from-chan)
=>
(0.6873518531956767
 0.6940302424998631
 0.07293052906941855
 0.7264083273536271
 0.4670275072317531)

但是,您可以通过以下方式完成同样的事情:

(def rand-nums (repeatedly rand))

所以,虽然您正在做的是一个伟大的思想实验,但找到一些具体的用例可能会更有帮助,然后您可能会收到更具体的想法。祝你好运!