2013-10-28 40 views
0

我開始了使用Clojure和,上一屆乘以:構建懶-SEQ通過,儘管有遞歸的理解,我有麻煩的「正確」的方式來建立一個懶惰-SEQ以下功能想着通過不斷

我想建立從中間C.我的第一個元素開始的所有頻率的列表將是120(中央C的頻率)。要獲得第二個元素,我乘的第一個元素,120,通過1.059463得到127.13556。到拿到第三我乘的第二個元素,127.13556,通過1.059463,等等等等......

什麼是Clojure中做到這一點的最好方法是什麼?

回答

4

可以使用iterate函數,該函數。

(iterate #(* % 1.059463) 120) 


如果您正計劃擴大到更復雜的東西這一點,那麼你會創建一個函數,爲lazy-seq呼叫內遞歸調用本身。 (這是iterate內部做。)

(defn increasing-frequencies 
    ([] (increasing-frequencies 120)) 
    ([freq] 
    (cons freq (lazy-seq (increasing-frequencies (* freq 1.059463)))))) 

(nth (increasing-frequencies) 2) ;; => 134.69542180428002 


如果你開始在一個緊湊的循環利用這一點,你可能還需要生成一個分塊懶起。這將預先計算未來幾年的元素,而不是一個接一個。

(defn chunked-increasing-frequencies 
    ([] (chunked-increasing-frequencies 120)) 
    ([freq] 
    (lazy-seq 
    (let [b (chunk-buffer 32)] 
     (loop [i freq c 0] 
     (if (< c 32) 
      (do 
      (chunk-append b i) 
      (recur (* i 1.059463) (inc c))) 
      (chunk-cons (chunk b) (chunked-increasing-frequencies i)))))))) 

注:我建議不要,直到你已經測量與計算各個元素性能問題這樣做。

1
(defn get-frequencies [] 
    (iterate #(* 1.059463 %) 120)) 

iterate

或者,如果你想使用lazy-seq明確,你可以這樣做:

(defn get-frequencies-hard [] 
    (cons 
    120 
    (lazy-seq 
    (map #(* 1.059463 %) (get-frequencies-hard))))) 

哪樣cons 120的每一個值的懶惰序列應用到地圖功能。