[英]Clojure pattern matching macro with variable arity that goes beyond explicit match cases
我正在将一些代码从Scheme转换为Clojure。 Scheme代码使用一个名为pmatch
的宏( https://github.com/webyrd/quines/blob/master/pmatch.scm )来将匹配参数模式pmatch
输出表达式。 具体来说,它允许变量捕获如下:
(define eval-expr
(lambda (expr)
(pmatch expr
[(zero? ,e)
(zero? (eval-expr e)))
...
在此用例中, eval-expr
某些输入表达式'(zero? 0)
应与第一种情况匹配。 列表的车匹配zero?
并且输入的arity匹配。 结果,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,这是由David Nolen和其他人编写的,但据我所知,这个宏看起来似乎
我正在尝试的另一个选项是一个鲜为人知的宏,称为defun
( https://github.com/killme2008/defun ),它定义了模式匹配函数。 这是一个例子:
(defun count-down
([0] (println "Reach zero!"))
([n] (println n)
(recur (dec n))))
我还在探索defun,看看它是否给了我所需的灵活性。 同时,是否有人建议如何在Clojure中进行模式匹配1.灵活的arity 2.变量捕获?
忽略递归应用程序:
(ns test.test
(:require [clojure.core.match :refer [match]]))
(def v [:x 0])
(def w [:x :y 0])
(defn try-match [x]
(match x
[:x e] e
[:x expr e] [expr e]
))
(try-match v)
;; => 0
(try-match w)
;; => [:y 0]
;; Matching on lists (actually, any sequences)
(defn try-match-2 [exp]
(match exp
([op x] :seq) [op x]
([op x y] :seq) [op x y]))
(try-match-2 '(+ 3))
;; => [+ 3]
(try-match-2 '(+ 1 2))
;; => [+ 1 2]
有关详细信息,请参阅https://github.com/clojure/core.match/wiki/Overview 。
另外,我建议你仔细看看Clojure解构 。 可以使用它完成很多事情而无需求助于core.match
,实际上你的用例已经涵盖了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.