В clojure, как применить «and» к списку?

В заключение, как мы можем применить и или любой другой макрос к списку?

Это не работает:

(apply and '(true false))

Поскольку apply не может принимать значение макроса.

Итак, как лучше всего проверить, все ли элементы списка верны?

23
задан viebel 9 February 2012 в 20:13
поделиться

2 ответа

В Clojure макросы не являются вещами первого класса , они не сочетаются совсем как функции, и вы не можете передать их другим функциям, и вы не можете apply их. Это потому, что они закончены и завершены до того, как будет подано любое заявление.

Обычно заключают макросы в функции в apply или передают их функциям

(defmacro my-macro [x y z] ...)

(apply #(my-macro %1 %2 %3) [1 2 3])

(map #(my-macro) [1 2 3] [:a :b :c] [a b c])

макрос чтения анонимных функций #( делает это так Легко, что макросы, не будучи первоклассными, на самом деле не доставляют неудобств. Просто попробуйте запомнить первое правило макроклуба

6
ответ дан 29 November 2019 в 01:54
поделиться
user=> (eval `(and ~@(list true false)))

false

user=> (eval `(and ~@ (list true true 1)))

1

Я цитирую синтаксис, а затем применяю большую кувалду, чтобы убрать скобки вокруг коллекции, и, поскольку я цитировал ее, я должен использовать eval. Это полезно, если вы создаете макрос, а переданная функция - это 'and'.

Таким образом, (list 1 2 3) кувалды становится 1 2 3.

Это один из способов, чрезвычайно ужасный, но он работает, поэтому я понял, что для меня приятно. Так что мое замыкание не велико, но я надеюсь, что этот пример макроса прояснит ситуацию.

(defmacro split-my-args-then-apply-fn
  "This is one terrible macro designed to show the use of 'and'."
  [fun coll & args]
  `(~fun ~@((apply juxt args) coll)))

Использование (никогда):

(split-my-args-then-apply-fn 
    and 
    {:something :true :something-else false} 
    :something :something-else)
0
ответ дан 29 November 2019 в 01:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: