我现在已经推出了自己的。它在向量、列表和哈希映射 val 上进行模式匹配(现在对集合和哈希映射键的模式匹配对我来说太难了)。
(defn match-sym? [v]
(and (symbol? v)
(re-find #"^%" (str v))))
(defn match
([f1 f2] (match f1 f2 (atom {})))
([v1 v2 dict]
(cond (or (and (list? v1) (list? v2))
(and (vector? v1) (vector? v2)))
(and (= (count v1) (count v2))
(->> (map #(match %1 %2 dict) v1 v2)
(every? true?)))
(and (hash-map? v1) (hash-map? v2))
(and (= (keys v1) (keys v2))
(->> (map #(match %1 %2 dict) (vals v1) (vals v2))
(every? true)))
(match-sym? v2)
(if-let [vd (@dict v2)]
(match v1 vd dict)
(do (swap! dict assoc v2 v1)
true))
:else (= v1 v2))))
及其用法:
> (match '(1 1) '(1 1))
;=> true
> (match '(1 1) '(%1 %1))
;=> true
> (match '(1 2) '(%1 %1))
;=> false
> (match '(let [x 1] (+ x 2))
'(let [%x 1] (+ %x 2)))
;=> true
> (match '(let [G__42879 (js-obj)]
(aset G__42879 "a" (fn [] (? G__42879.val)))
(aset G__42879 "val" 3) G__42879)
'(let [%x (js-obj)]
(aset %x "a" (fn [] (? %x.val)))
(aset %x "val" 3) %x))
;=> true