簡體   English   中英

為什么過濾懶惰序列在clojure中不起作用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM