我正在将Scheme中的一些代码翻译成Clojure。 方案代码使用名为pmatch
(https://github.com/webyrd/quines/blob/master/pmatch.scm)的宏将匹配参数设置为输出表达式。具体而言,它允许可变捕获如下:Clojure模式匹配宏与变量arity,超越了明确的匹配情况
(define eval-expr
(lambda (expr)
(pmatch expr
[(zero? ,e)
(zero? (eval-expr e)))
...
在该使用实例中,一些输入表达式eval-expr
,'(zero? 0)
,应该匹配的第一例。列表的车匹配zero?
和输入匹配。因此,0绑定到e并传递给(zero? (eval-expr e))
,并且此expr是递归计算的。 在Haskell,它支持原生模式匹配,代码可能转换为类似以下内容:
Prelude> let evalexpr "zero?" e = (e == 0) -- ignoring recursive application
Prelude> evalexpr "zero?" 0
True
在Clojure中,我第一次尝试用core.match(https://github.com/clojure/core.match),写由大卫·诺伦替代pmatch和其他人,但是,据我所知,这个宏似乎
- 只支持每次使用参数的单元数
- 仅支持明确的匹配,而不是基于属性的匹配(可作为后卫)
我正在尝试的另一个选择是名为defun
(https://github.com/killme2008/defun)的较少已知的宏,它定义了模式匹配函数。这里有一个例子:
(defun count-down
([0] (println "Reach zero!"))
([n] (println n)
(recur (dec n))))
我还在探索defun,看看它是否给了我需要的灵活性。 同时,有没有人有如何在Clojure模式匹配的建议1.柔性阵列2.变量捕获?
谢谢你的回应。你介意提供额外的解释吗? –
当然,我不介意,只是请让我知道什么不清楚?我特别提供了一个你称之为“灵活的元组”的例子 - 变长模式和变量绑定(你称之为“变量捕获”)。它似乎直接解决你的用例,除非我错过了一些东西。 –
你有没有机会知道如何将你的例子的逻辑扩展到列表? (例如(try-match'(+ 2 2))=> 4) –