簡體   English   中英

具有可變arity的Clojure模式匹配宏超出了顯式匹配情況

[英]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和其他人編寫的,但據我所知,這個宏看起來似乎

  1. 每次使用只支持一個參數arity
  2. 僅支持顯式匹配,而不是基於屬性的匹配(可用作警衛)

我正在嘗試的另一個選項是一個鮮為人知的宏,稱為defunhttps://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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM