2012-03-29 67 views
1

假設我有表示爲Clojure的關鍵字實體的一個特設的層次,就像這樣:如何使用clojure.core.match與層次結構進行匹配?

(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:number)。


背景:我用Clojure,在那裏我需要根據其名稱和操作數來組裝我的指令編寫玩具x86彙編。目前,我的代碼,包括像:

(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)}) 

(即,INT指令彙編爲兩個字節,0xcd隨後中斷號,除非這是一個INT 3在這種情況下,只有一個字節,0xcc)。然而,我覺得這有點醜陋,我正在尋找一種更優雅的方法。所以不是我想說沿

(asm-match [(-> instr name keyword) op1 op2] 
    ;; other options 
    [:int 3 nil]  {:opcode 0xcc} 
    [:int :imm nil] {:opcode 0xcd, :immediate (imm 8 op1)}) 

回答

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)}) 

線的東西這難道不是爲你工作?