我受到clojure's 1.5 cond->
macro.
类似地,我想创建一个同样想法的宏,应用于函数map
。但是,我不知道从哪里开始。
例如,我找不到cond->
的来源。 (可能是因为它尚未发布)
有什么建议吗?
答案 0 :(得分:3)
答案 1 :(得分:2)
来自托盘项目人员的各种threading macros包括apply-map->看起来很接近,虽然不是你想要的。
(letfn [(apply-map-
[arg f arg-coll]
`(let [arg# ~arg]
(apply ~f arg#
~@(butlast arg-coll)
(apply concat ~(last arg-coll)))))]
(defmacro apply-map->
"Apply in a threaded expression.
e.g.
(-> :a
(apply-map-> hash-map 1 {:b 2}))
=> {:a 1 :b 2}"
[arg f & arg-coll]
(apply-map- arg f arg-coll))
也许会有足够的例子让你挑选出你需要的东西。
答案 2 :(得分:1)
如果我理解-您想编写一个宏,其中包含部分函数调用的列表,并为每个宏添加map
(或apply map
)到开头以及前一个结果到底?
虽然这不能直接回答如何编写该宏,但我想指出您有几种选择。
map
对于纯函数总是如此:
(=
(map g (map f coll))
(map (comp g f) coll))
重构后的版本只遍历一次集合,而无需进行任何中间集合。
这是线程的样子:
(=
(->> coll
(map f)
(map g))
(map #(->> % f g) coll))
Here's a concrete example in JS.
Transducers是Clojure中执行此类操作的另一种模式,其作用不仅限于map
。它们是对reducer函数的抽象。如果在没有集合的情况下调用Clojure的map
/ filter
/ reduce
(等等),则会创建一个转换器。您可以将它们与comp
链接起来,并在各种上下文中使用它们(懒惰,渴望,可观察,等等)。 Rich Hickey's talk是一个很好的介绍。