我希望使用以下代码生成所有小于10的2的倍数
(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
无法知道谓词为真的项数是有限的,因此它将永远保持
为什么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
,而不是filter
。