[英]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.