2017-03-05 36 views
2

考慮下面的代碼片斷:「反覆」在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)) 

哪一個當然沒有被緩衝,但它可能會給我想要的東西。

+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)))) 

定義的序列:

(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)) 

因此,儘管您正在做的是一個偉大的思想實驗,但找到一些具體的用例可能會更有幫助,然後您可能會收到更具體的想法。祝你好運!