[英]Clojure- why doesn't this piece of code work in clojure, is there some lazy evaluation gotcha I am missing?
[英]Why filter on a lazy sequence doesn't work in clojure?
我希望使用以下代碼生成小於10的兩個倍數
(filter #(< % 10) (iterate (partial + 2) 2))
預期產量:
(2 4 6 8)
但是,出於某種原因,repl只是不提供任何輸出?
但是,下面的代碼工作得很好......
(filter #(< % 10) '(2 4 6 8 10 12 14 16))
我知道一個是懶惰序列,一個是常規序列。 這就是原因。 但是如果我希望從懶惰序列中過濾掉所有小於10的數字,我怎么能克服這個問題呢?
(iterate (partial + 2) 2)
是一個無限的序列。 filter
無法知道謂詞為真的項目數是有限的,所以當你意識到序列時它將永遠存在(參見Mark的回答)。
你想要的是:
(take-while #(< % 10) (iterate (partial + 2) 2))
我想我應該注意到Diego Basch的答案在其論證中並不完全正確:
filter
無法知道謂詞為true的項目數是有限的,因此它將永遠持續下去
為什么filter
應該知道一些事情呢? 實際上filter
在這種情況下工作正常。 可以對延遲序列應用filter
並獲取另一個延遲序列,該序列表示可能無限的過濾數字序列:
user> (def my-seq (iterate (partial + 2) 2)) ; REPL won't be able to print this
;; => #'user/my-seq
user> (def filtered (filter #(< % 10) my-seq)) ; filter it without problems
;; => #'user/filtered
user>
這里的關鍵細節是,當實際序列不確定時(因此Clojure知道這一點),人們永遠不應該嘗試(通過在OP的情況下打印)延遲序列。
當然,這個例子僅用於演示目的,你應該take-while
這里使用take-while
,而不是filter
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.