2014-01-12 2 views
2

В упражнении Clojure, над которым я работаю, у меня есть несколько методов, все из которых просто используют identity в качестве функции отправки. Например:Clojure: Определить мультиметоды из списка символов?

(defmulti amount identity) 
(defmulti bottles identity) 
(defmulti pronoun identity) 
(defmulti action identity) 
(defmulti pred identity) 

Поскольку все они используют один и тот же identity функцию для отправки, я хотел бы просто перебирать имена и называть defmulti для каждого имени, а не повторять defmulti звонки. Я попытался это:

(doseq [m '(amount bottles pronoun action pred)] 
    (defmulti m identity)) 

Однако, когда я делаю, что кажется, как будто defmulti не имеет должный эффект, как, когда я позже использовать defmethod для любого из Многометодных имен, я получаю сообщение об ошибке, таких как:

(defmethod amount 0 [n] "whatever") 

CompilerException java.lang.RuntimeException: Unable to resolve symbol: amount in this context, compiling:(NO_SOURCE_PATH:1:1) 

можно перебрать список символов или имен и вызвать defmulti для каждого из них, и если да, то как это может быть сделано?

+1

Поскольку 'defmulti' макрос он получает символ' M' в качестве первого аргумента и не связанное значение в 'doseq'. То, что фактически делает «доза», - это просто определение мультиметода 'm' кучу раз. –

ответ

6

Вы можете создать макрос, который оборачивает над defmulti и делает нужную вещь:

(defmacro defidmulti [names] 
    `(do [email protected](for [m names] 
      `(defmulti ~m identity)))) 

(defidmulti [amount bottles pronoun action pred])