Clojure线程宏
我不确定这是不是最好的发帖地点,但为什么不行呢?线程宏没有将seq的结果传递到Clojure线程宏,clojure,Clojure,我不确定这是不是最好的发帖地点,但为什么不行呢?线程宏没有将seq的结果传递到(map str) 您使用的是宏,它将每个表单作为下一个表单的第二项插入,如下所示: (-> (* x y) str seq (map str)) (-> (str (* x y)) seq (map str)) (-> (seq (str (* x y))) (map str)) (map (seq (str (* x y))) str) 您需要的是宏: 正如Elogent指出的那样,宏将参数放在
(map str)
您使用的是宏,它将每个表单作为下一个表单的第二项插入,如下所示:
(-> (* x y) str seq (map str))
(-> (str (* x y)) seq (map str))
(-> (seq (str (* x y))) (map str))
(map (seq (str (* x y))) str)
您需要的是宏:
正如Elogent指出的那样,宏将参数放在了错误的位置。一般来说,在使用宏(尤其是编写宏)时,了解
macroexpand-1
并将其与clojure.pprint/pprint
相结合有助于了解实际运行的内容:
user> (clojure.pprint/pprint
(macroexpand-1
'(-> (* x y)
str
seq
(map str))))
(map (seq (str (* x y))) str)
nil
我们可以看到它看起来不太正确。因此,接下来我们将对其进行处理,直到它扩展到我们所期望的:
user> (clojure.pprint/pprint
(macroexpand-1
'(->> (* x y)
str
seq
(map str))))
(map str (seq (str (* x y))))
nil
有多种线程宏可帮助处理此类情况,尤其是as->
,当您需要使用重要输入的第一个和最后一个参数对函数执行线程时,可以为线程值指定一个显式名称:
user> (as-> (* 7 42) x
(str x)
(seq x)
(map str x))
("2" "9" "4")
这里有一个很好的选择(从右到左阅读):
这可能在您想将转换应用到应用程序的上下文中有用(我欢迎受此主题的P<)的批评。您也可以考虑使用<代码> IT > >代码>线程窗体,这是为了避免线程第一次对线程最后的担忧。请考虑此代码:
(ns clj.core
(:use tupelo.core))
(defn a [x y]
(it-> (* x y)
(str it)
(seq it)
(map str it)))
(spyx (a 8 8))
(defn -main [] )
产生:
(a 8 8) => ("6" "4")
it->
宏使用占位符it
显式地选择每个后续表单的结果放置位置。这是简化代码和避免此类错误的一种简单方法。您的意图是好的,但由于您已经将转换和数据组合到a
函数中,因此无法实现我会从这个方法中得到任何东西。谢谢你的建议。它看起来像一个非常可爱的图书馆。
(defn a [x y]
((comp (partial map str) seq str *)
x y))
(ns clj.core
(:use tupelo.core))
(defn a [x y]
(it-> (* x y)
(str it)
(seq it)
(map str it)))
(spyx (a 8 8))
(defn -main [] )
(a 8 8) => ("6" "4")