了解如何执行效果的心理框架是什么? 例如,我无法理解为什么在这种情况下
(take 5 (map prn (range 10)))
REPL打印10个数字
0 1 2 3 4 5 6 7 8 9&在其他情况下
(transduce (comp (take 5) (map prn)) conj [] (range 10))
它只打印5
0 1 2 3 4,但我们在两个示例中都有
take 5
?
答案 0 :(得分:1)
1)您的第一个代码段(take 5 (map prn (range 10)))
实际上为您提供了5个结果。
这里是(map prn [])
的REPL示例,它为您提供长度为10的LazySeq
。它包含nil
,即prn
函数返回的内容。
user=> (map prn (range 10))
0
1
2
3
4
5
6
7
8
9
(nil nil nil nil nil nil nil nil nil nil)
然后,当您在(take 5 )
上方应用LazySeq
时,您会获得5 nil
次。
user=> (def some-data (map prn (range 10)))
#'user/some-data
user=> (take 5 some-data)
0
1
2
3
4
5
6
7
8
9
(nil nil nil nil nil)
如果您还不相信,请打印尺寸,
user=> (count (take 5 some-data))
5
您可能也想阅读文档,
user=> (doc take)
-------------------------
clojure.core/take
([n] [n coll])
Returns a lazy sequence of the first n items in coll, or all items if
there are fewer than n. Returns a stateful transducer when
no collection is provided.
nil
2)在您的第二个片段中,您先说take 5
然后应用prn
,这就是为什么它只打印5个元素。
user=> (def tform (comp (take 5) (map prn)))
#'user/tform
user=> (transduce tform conj [] (range 10))
0
1
2
3
4
[nil nil nil nil nil]
为了更好地理解它,请参阅以下示例来过滤奇数,(比official transduce
example稍微修改一下)
user=> (def xform (comp (take 5) (filter odd?)))
#'user/xform
user=> (transduce xform conj (range 1 100))
[1 3 5]
答案 1 :(得分:1)
我觉得你误会了什么。 prn
函数只打印一个返回nil
的值:
user=> (prn 42)
42
nil
因此,当将它应用于集合时,您将只打印接收nil
s序列的所有项目:
user=> (map prn (range 10))
0
1
...
8
9
(nil nil nil nil nil nil nil nil nil nil)
take
函数返回一个子序列,收集下一个项目,直到它变得小于提供的值。由于所有nil
都小于5
,因此将返回所有项目。
第二个例子也有同样的错误。请仔细阅读文档。
还有一些一般性说明:在处理集合时,请勿使用prn
或任何相关函数(pr
,prn-str
和其他函数)。仅打印最终结果。您的代码应该没有副作用。使用REPL评估代码的特定片段。在单独的函数上分解线程宏然后它会增长。但是不要使用印刷品。