2016-08-20 4 views
1

SchemeからClojureにいくつかのコードを翻訳しています。 Schemeコードでは、pmatchhttps://github.com/webyrd/quines/blob/master/pmatch.scm)というマクロを使用して、一致する引数を出力式にパターン化します。この使用例で明示的なマッチの場合を超えて、可変アリティを持つClojureパターンマッチングマクロ

(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のでは 、コードは次のように変換されることがあります

のClojureで
Prelude> let evalexpr "zero?" e = (e == 0) -- ignoring recursive application 
Prelude> evalexpr "zero?" 0 
True 

、私は最初のデビッド・ノレンによって書かれた、core.match(https://github.com/clojure/core.match)とpmatchを代用してみましたその他、しかし、私の知る限り、このマクロは

  1. のみ使用あたりの引数の単一アリティをサポートしているようだ
  2. のみ明示的なマッチングではなく、プロパティベースのマッチング(ガードとして利用可能)をサポートし

私が試しているもう1つの選択肢は、パターンマッチング機能を定義するdefunhttps://github.com/killme2008/defun)というあまり知られていないマクロです。ここに例があります:

(defun count-down 
    ([0] (println "Reach zero!")) 
    ([n] (println n) 
    (recur (dec n)))) 

私はそれが私に必要な柔軟性を与えるかどうかを調べるためにまだ検討しています。 一方、誰もClojureでのパターンマッチング方法を提案していますか?1.柔軟なアリティ2.可変キャプチャ?

答えて

3

再帰的なアプリケーションを無視:

(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 destructuringをよく見ることをお勧めします。 core.matchに頼らずに多くのことを行うことができますが、実際にはユースケースがカバーされています。

+0

ご回答いただきありがとうございます。詳しい説明をしてもらえますか? –

+1

確かに、私は気にしません、あなたは私に不明なことを教えてもらえますか?可変長パターンと可変バインディング(変数キャプチャと呼んでいたもの)を具体的に示しました。何かが欠落していない限り、ユースケースに直接対処しているようです。 –

+0

あなたの事例の論理をリストにどのように拡張するのか、多分知っていますか? (例えば、(試合合致 '(+2 2))=> 4) –

関連する問題