Clojure元编程动态选择记录(初学者!)

时间:2015-04-18 02:16:19

标签: clojure metaprogramming

我有一堆实现协议P的记录(A B C)。

我想编写一个方法,它将选择一种记录类型,构造它,然后在其上调用一个方法。

例如,如果我有一个记录列表 (def types '(A B C))我想做(->(first types) 1 2 3)

之类的事情

1 个答案:

答案 0 :(得分:1)

嗯,函数也是值,可以存储在数据结构中并从中检索。所以你应该能够以一些方便的格式存储你想要选择的构造函数,并从那里使用它们。类似的东西:

(defrecord foo [x y])

(defrecord bar [x y z])

(def constructors [->foo ->bar])

((first constructors) 4 5) ;;=> #user.foo{:x 4, :y 5}

;;or

(apply (second constructors) [20 true :baz]) ;;=> #user.bar{:x 20, :y true, :z :baz}

(-> (second constructors) (apply '(59 -30 false))) ;;=> #user.bar{:x 59, :y -30, :z false}

或者您甚至可以完全跳过数据结构:

(defn quxx [n a-map]
  ((if (< 25 n) map->foo map->bar) a-map))

(quxx 2 {:x 3 :y 9 :z -200}) ;;=> #user.bar{:x 3, :y 9, :z -200}

(quxx 29 {:x 3 :y 9 :z -200}) ;;=> #user.foo{:x 3, :y 9, :z -200}