我的灵感来自clojure的1.5 cond->
宏
同样,我想创建一个具有相同思想的宏,应用于函数map
。但是,我不知道从哪里开始。
例如,我找不到cond->
的来源。(可能是因为它还没有发布)
有什么建议吗?
有cond->
的来源https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6742
有各种各样的线程宏来自托盘项目的人,包括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))
也许会有足够的例子让你挑选你需要的
如果我理解的话——你想写一个宏,它接受部分函数调用的列表,并且对于每个宏,将map
(或apply map
)添加到开始,并将前一个结果添加到结束?
虽然这并没有直接回答如何编写宏,但我想指出您有几个替代方案。
提出map
这对于纯函数总是成立的:
(=
(map g (map f coll))
(map (comp g f) coll))
重构后的版本只遍历集合一次,不需要进行中间集合。
下面是使用threading的样子:
(=
(->> coll
(map f)
(map g))
(map #(->> % f g) coll))
下面是JS中的一个具体例子:
<标题>传感器h1> 能器是Clojure中做这种事情的另一种模式,它不仅仅适用于map
。它们是对减速器函数的一种抽象。Clojure的map
/filter
/reduce
(等)将在没有集合的情况下创建一个换能器。您可以将它们与comp
链接,并在各种上下文中使用它们(lazy, eager, observable,等等)。Rich Hickey的演讲是一个很好的介绍。 标题>