Macros Clojure:可以在一个condp子句中创建一个宏来创建这两个元素吗?
condp条款如下所示:Macros Clojure:可以在一个condp子句中创建一个宏来创建这两个元素吗?,macros,clojure,Macros,Clojure,condp条款如下所示: "plet" (make-adj 2 "ète") "iet" (make-adj 2 "ète") "nin" (make-adj 1 "gne") 我想将该条件添加到make adj函数调用中,而不在一行中重复该条件两次。我想要一个宏来打开这个: (test-make-adj "plet" 2 "ète") (test-make-adj "iet" 2 "ète") (test-make-adj "nin" 1 "gne")
"plet" (make-adj 2 "ète")
"iet" (make-adj 2 "ète")
"nin" (make-adj 1 "gne")
我想将该条件添加到make adj
函数调用中,而不在一行中重复该条件两次。我想要一个宏来打开这个:
(test-make-adj "plet" 2 "ète")
(test-make-adj "iet" 2 "ète")
(test-make-adj "nin" 1 "gne")
为此:
"plet" (make-adj 2 "ète" "plet")
"iet" (make-adj 2 "ète" "iet")
"nin" (make-adj 1 "gne" "nin")
首先是一个函数,用于生成一个condp子句
(defn test-make-adj [x num y]
`(~x (make-adj ~num ~y ~x)))
然后使用宏将子句组装成condp表达式
(defmacro adj-condp [pred expr & clauses]
`(condp ~pred ~expr
~@(mapcat test-make-adj clauses)))
ps:我不在我的repl,所以我无法测试,请编辑:)
condp
具有内置功能以支持此类功能:
(condp #(if (= %1 %2) %1) condition
"plet" :>> #(make-adj 2 "ète" %)
"iet" :>> #(make-adj 2 "ète" %)
"nin" :>> #(make-adj 1 "gne" %))
#(if(=%1%2)%1)
是一个二进制函数,它检查其参数是否相等,如果相等,则返回第一个参数,否则返回nil
:>
使得对条件
上的谓词求值的结果,例如“plet”
传递给#(make adj…
函数。对于上述谓词,这意味着如果(=“plet”条件)
为真
,则“plet”
将传递到#(make adj…
)。有关更多信息,请参见(doc condp)
如果这仍然感觉键入太多,可以创建一个助手函数:
(defn make-adj* [n s]
(fn [c] (make-adj n s c))
然后像这样使用它:
(condp #(if (= %1 %2) %1) condition
"plet" :>> (make-adj* 2 "ète")
...)
我对代码进行了一些修改。除了删除两个小错误外,我还将
(apply concat(map…)
替换为mapcat
,并根据风格调整了缩进。希望你能接受。