我正在將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) –