【发布时间】:2011-06-14 18:19:18
【问题描述】:
作为我previous question 的后续行动,我正在尝试在 Clojure 中实现一个简单的模式匹配。
我想要以下内容:
(match target
[ub] expr1 ; ub should be bound to actual value in expr1
['< ub] expr2 ; match the literal less-than symbol
; and ub should be bound to actual value in expr2
[lb ub] expr3 ; lb and ub should be bound to actual values in expr3
:else expr4 ; default case if none match
)
用法:
(match [< 5.0] ...)
应该安排在运行时执行expr2。
我想写一个宏,但我不确定扩展。
我正在考虑将每个 case-and-clause 扩展为 let,并绑定到内部变量,并检查文字符号 ('<) 是否与模式匹配。也许是第二种模式(['< ub]):
(let [[sym1 ub] pattern]
(if (= '< sym1)
expr1)
我需要使用(gensym) 进行绑定吗?怎么样?
大图:
(range-case target
[0.0 < 1.0] :greatly-disagree
[< 2.0] :disagree
[< 3.0] :neutral
[< 4.0] :agree
[5.0] :strongly-agree
42 :the-answer
:else :do-not-care)
我正在尝试匹配 [...] 模式并将它们转换为以下内容:
[ub] (if previous-ub `(and (<= ~previous-ub ~target) (<= ~target ~ub))
`(< ~target ~ub))
['< ub] (if previous-ub `(and (<= ~previous-ub ~target) (< ~target ~ub))
`(< ~target ~ub))
[lb ub] `(and (<= ~lb ~target) (<= ~target ~ub))
['< lb ub] `(and (< ~lb ~target) (<= ~target ~ub))
[lb '< ub] `(and (<= ~lb ~target) (< ~target ~ub))
['< lb '< ub] `(and (< ~lb ~target) (< ~target ~ub))
我有一个 cond 来检查 case 部分是否为向量。这种模式匹配应该发生在这种情况下。
【问题讨论】:
-
您是否查看过现有的 Clojure 模式匹配工具?例如 matchure 看起来很有趣:spin.atomicobject.com/2010/04/25/…
-
@mikera:是的。我只是想弄清楚宏,并希望编写它们会有所启发。
-
啊,那太酷了。只要你想学习造轮子的艺术,重新发明轮子就完美了!
标签: macros clojure pattern-matching