【发布时间】:2020-05-07 13:29:21
【问题描述】:
我有以下功能来收集数据交易报告,这个earlier question的输出。
(def recreate-database
"Defines a function which when called will call each of the four given
functions and return a collection containing the output of each."
(juxt pt1-transact-schema
pt1-transact-data
pt2-transact-schema
pt2-transact-data))
下一步是这些函数中的每一个本身可能调用的不是一个而是一系列事务,因此所需的完整结果将是用于初始数据库构建的事务报告的嵌套集合。
我有以下,这是不合适的,因为当从上面的recreate-database调用时,只有最后一个交易报告通过,一个函数当然只返回它的最终形式。
(defn pt1-transact-data []
(d/transact conn {:tx-data pt1-user-data})
(d/transact conn {:tx-data pt1-path-data})
(d/transact conn {:tx-data pt1-series-data}))
所以我到了下面
(defn pt1-transact-data []
(map identity
[(d/transact conn {:tx-data pt1-user-data})
(d/transact conn {:tx-data pt1-path-data})
(d/transact conn {:tx-data pt1-series-data})
(d/transact conn {:tx-data pt1-path-series-data})]))
这很好用,但仍然存在偶然的复杂性。 map identity 在语言上相对于此处的预期含义而言是低级的。
因此想到,我们只需要“实现序列”,所以我提取了:
(defn realize-all [coll] (map identity coll))
然后我想起了doall。
在这里也可以使用它。
那么,这和doall 所做的一样吗?
我从(source doall) 注意到它看起来不一样,导致dorun,导致...recur。
所以map identity 或doall 或dorun 似乎在这里起到类似的作用。
这些是等价的吗?还有什么要说的吗?
【问题讨论】:
-
map identity产生另一个需要在任何事情发生之前实现的惰性序列。我猜你是在 repl 上调用它,这让你认为这是实现它的东西(当 repl 尝试打印结果时,它就会实现)。dorun和doall是等价的,除了doall保留 seq 的头部并返回它。如果您打算不对返回的序列做任何事情,请使用dorun。它将使用更少的内存并更清楚地说明您的意图。 -
你也可以使用
mapv,这是地图的渴望版 -
@mwal 请注意,这个问题本质上与 Datomic 无关,而与 Clojure 无关,因此您可能需要删除 Datomic 标记。我还会修改标题,例如“如何在 Clojure 的集合中返回多个连续结果”。