如何使用clojure.core.match匹配层次结构?

时间:2012-03-29 12:24:09

标签: clojure pattern-matching

假设我有一个以Clojure关键字表示的实体的临时层次结构,如下所示:

(def h 
  (-> (make-hierarchy)
      (derive :animal :feline)
      (derive :feline :cat) 
      (derive :feline :lion) 
      (derive :feline :tiger)))

最好的方法(最好使用clojure.core.match)来编写match-hierarchy函数,以便这些人为的例子能够返回预期的结果:

(defn example [x y]
  (match-hierarchy h [x y]
    [:cat :cat] 0
    [:cat :feline] 1
    [:cat :animal] 2
    [:animal :animal] 3))

(example :cat :cat)
;=> 0

(example :cat :tiger)
;=> 1

(example :tiger :tiger) 
;=> 3

即,match-hierarchy应该返回与第一个子句相对应的值,该子句的元素都等于匹配值的相应元素,或者它的(直接或间接)祖先?

我很高兴使用自定义而不是make-hierarchy来创建层次结构。如果有其他选项,我也很高兴不使用core.match。但是,我需要它来处理预先存在的类的对象,例如数字(例如,我希望能够说3:positive-integer:integer是{{1} 1}})。


背景:我正在Clojure中编写一个玩具x86汇编程序,我需要根据其名称和操作数来汇编我的指令。目前我的代码包括:

:number

(即,INT指令汇编为两个字节,(match [(-> instr name keyword) (operand-type op1) (operand-type op2)] ;; other options [:int :imm nil] (if (= op1 3) {:opcode 0xcc} {:opcode 0xcd, :immediate (imm 8 op1)}) 后跟中断号,除非它是0xcd,在这种情况下它只有一个字节,{{ 1}})。然而,我发现这有点难看,我正在寻找一种更优雅的方法。所以相反,我想说点什么

INT 3

1 个答案:

答案 0 :(得分:4)

(match [(-> instr name keyword) op1 (operand-type op1) (operand-type op2)]
  [:int 3 :imm nil] {:opcode 0xcc}
  [:int _ :imm nil] {:opcode 0xcd, :immediate (imm 8 op1)})

这不适合你吗?