什么是心理框架,以了解如何执行效果?

时间:2018-01-23 06:04:31

标签: clojure

了解如何执行效果的心理框架是什么? 例如,我无法理解为什么在这种情况下

(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

2 个答案:

答案 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或任何相关函数(prprn-str和其他函数)。仅打印最终结果。您的代码应该没有副作用。使用REPL评估代码的特定片段。在单独的函数上分解线程宏然后它会增长。但是不要使用印刷品。