创建一个 clojure 映射线程宏 ( 映射-> )



我的灵感来自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的演讲是一个很好的介绍。

最新更新