В заключение, как мы можем применить and
или любой другой макрос к списку?
Это не работает:
(apply and '(true false))
Потому что apply
не может принимать значение макроса.
Итак, как лучше всего проверить, все ли элементы списка верны?
В заключение, как мы можем применить and
или любой другой макрос к списку?
Это не работает:
(apply and '(true false))
Потому что apply
не может принимать значение макроса.
Итак, как лучше всего проверить, все ли элементы списка верны?
Вместо этого вы можете сделать это:
(every? identity '(true false))
Дополнительную информацию см. в этой теме.
В 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])
макрос чтения анонимных функций #(
делает это настолько простым, что макросы, не относящиеся к первому классу, на самом деле не доставляют неудобств. Просто попробуйте запомнить первое правило макроклуба
Вы также можете сделать это: (apply = true '(true false))
user=> (eval `(and ~@(list true false)))
false
user=> (eval `(and ~@ (list true true 1)))
1
Я цитирую синтаксис, а затем применяю большую кувалду, чтобы удалить скобки вокруг коллекции, и, поскольку я процитировал ее, должен использовать eval. Это полезно, если вы создаете макрос и в него передается функция «и».
так что (list 1 2 3)
кувалда становится 1 2 3
.
Это один из способов, очень ужасный, но он работает, так что у меня это получилось, и это приятно. Итак, мой clojure не очень хорош, но я надеюсь, что этот пример макроса прояснит ситуацию.
(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)