[英]Generate lazy seq with recursion in Clojure?
我是clojure的新手,目前正在努力使用loop / recur
。 問題基本上就是為什么我的'自定義' range
功能。 不返回懶惰序列。 我的實現有什么問題,或者你不應該在這種情況下使用遞歸嗎?
(defn my-range
[nr]
(loop [l nr acc '()]
(if (< l 1)
acc
(recur (dec l) (conj acc l)))))
當我運行它:
> (time (take 10 (my-range 100000))) ;; "Elapsed time: 85.443 msecs"
> (time (take 10 (range 100000))) ;; "Elapsed time: 0.095 msecs"
非常大的時差使我相信列表首先構建然后10。
你不在my-range
使用任何惰性結構。 由於您從最后開始組裝列表並朝着開頭方向工作,因此訪問前十個元素的唯一方法是首先實現所有其他元素。
懶惰的序列從頭開始,一直到最后,如下所示:
(defn my-range
([end]
(my-range 1 end))
([start end]
(when (<= start end)
(lazy-seq (cons start (my-range (inc' start) end))))))
這里的訣竅是你沒有返回一個已實現的序列。 而是返回一個存儲此函數的對象:
#(cons start (my-range (inc' start) end))
當有人在該對象上調用seq
時,它將調用上述函數,緩存其結果並返回該結果。 對seq
未來調用將只返回緩存的結果。 但請注意,傳遞給cons
的第二個參數也是一個惰性序列(因為對my-range
的調用會返回一個lazy-seq
),因此反過來,它只會在必要時實現。
為了完整起見,編寫此函數的另一種方法如下:
(defn my-range
[end]
(take end (iterate inc' 1)))
這工作,因為iterate
,並take
兩回懶序列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.