試圖用Clojure以下,期待有類非延遲序列返回:我如何偷懶序列轉換爲非懶惰Clojure中
(.getClass (doall (take 3 (repeatedly rand))))
然而,這仍然返回clojure.lang.LazySeq
。我的猜測是doall
確實評估整個序列,但返回原始序列,因爲它仍然用於記憶。
那麼從懶惰創建非惰性序列的慣用方法是什麼?
試圖用Clojure以下,期待有類非延遲序列返回:我如何偷懶序列轉換爲非懶惰Clojure中
(.getClass (doall (take 3 (repeatedly rand))))
然而,這仍然返回clojure.lang.LazySeq
。我的猜測是doall
確實評估整個序列,但返回原始序列,因爲它仍然用於記憶。
那麼從懶惰創建非惰性序列的慣用方法是什麼?
doall是你所需要的。僅僅因爲seq有類型LazySeq並不意味着它有待評估。懶惰的seqs緩存他們的結果,所以你所需要做的只是一次走懶惰seq(就像doall一樣),以強制所有這些,從而使其不會懶惰。 seq確實不是強制對整個集合進行評估。
I'已經將其改爲已接受的答案。在相關說明中,通過什麼方法可以確定LazySeq是否先前已經過評估? – 2009-10-29 14:16:31
我相信你只是叫'實現?'。 – toofarsideways 2012-02-01 02:40:14
可能應該有一個「實現」操作來匹配'實現?'。 – 2017-02-01 14:07:28
這在某種程度上是一個分類問題。 懶惰序列只是一種類型的序列,因爲它是一個列表,向量或映射。因此,答案當然是「這取決於你想要得到什麼類型的非懶序列:
(doall ...)
(apply list (my-lazy-seq)) OR (into() ...)
(vec (my-lazy-seq))
您可以擁有最適合您需要的任何類型的序列。
這是最好的答案。 – 2014-07-25 16:20:17
接受的答案在技術上是正確的,但是這個答案對我來說最有用。我試圖在vector上映射一個函數,然後將結果吐在一個文件中,甚至在調用doall之後,文件中包含「[email protected]」而不是序列的內容。在返回的值映射上調用vec讓我得到了我需要吐出的文件。 – 2015-11-23 23:17:29
@JesseRosalia很高興知道所有SO中唯一的Rich Hickey響應在技術上是正確的。 ;-) – 2016-03-15 21:02:44
這個有錢人似乎知道他的clojure,是絕對正確的。
Buth我覺得這個代碼片段,使用你的榜樣,可能是一個有益的補充這樣一個問題:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
事實上型並沒有改變,但實現已經
我這個迷迷糊糊這個blog關於doall
的帖子不是遞歸的。爲此,我發現在帖子中的第一條評論做了訣竅。沿着線的東西:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
我發現這個有用的單元測試,我想強制的map
一些嵌套應用評估,以迫使一個錯誤條件。
我很驚訝沒有人問你爲什麼要關注'doall'的返回值的實際類型 – tar 2017-11-01 17:14:57
你可以轉換成矢量:'(vec(take 3(repeated rand)))' – Kris 2018-01-23 12:33:50