是否有可用于比较模式宏形式的工具/功能? [英] Is there a tool/function that can be used to compare patterns macro forms?

查看:59
本文介绍了是否有可用于比较模式宏形式的工具/功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在某些宏中使用了 gensym 函数,因此很难测试:

I use the gensym function in some of my macros which then makes it hard to test:

so某些宏的扩展可能是:

so the expansion of some macro might be:

'(let [G__10458 (js-obj)] 
   (aset G__10458 "a" (fn [] (? G__10458.val))) 
   (aset G__10458 "val" 3) G__10458)

我要测试的是它是否与这种类型的图案匹配:

what I want is to test that it matches up to this type of patten:

'(let [%1 (js-obj)] 
   (aset %1 "a" (fn [] (? %1.val))) 
   (aset %1 "val" 3) %1)

clojure.core.match 库或执行此操作的其他模式匹配库?

Is there something in the clojure.core.match library or another pattern matching library that does this?

推荐答案

我现在已经自己准备好了。它在向量,列表和哈希映射值上进行模式匹配(现在,集合和哈希映射键上的模式匹配对我来说太难了)。

I've rolled my own for now. It pattern matches on vectors, lists and hash-map vals (pattern matching on sets and hash-map keys are too hard for me right now).

(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

这篇关于是否有可用于比较模式宏形式的工具/功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆