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

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

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

(apply and '(true false))

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

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


person viebel    schedule 09.02.2012    source источник
comment
возможный дубликат уменьшить или применить с помощью логических функций в Clojure   -  person amalloy    schedule 10.02.2012


Ответы (4)


Вместо этого вы можете сделать это:

(every? identity '(true false))

Дополнительную информацию см. в этой теме.

person Kai Sternad    schedule 09.02.2012
comment
Что-нибудь более аккуратное для этого варианта использования в последних версиях? - person matanster; 01.07.2018

В 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])

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

person Arthur Ulfeldt    schedule 09.02.2012
comment
Но этот подход рухнет, когда макрос получит переменное количество аргументов. - person viebel; 10.02.2012
comment
ты нарушаешь первое правило клуба макросов... да, даже абстракция макроса дает утечку :( - person Arthur Ulfeldt; 10.02.2012

Вы также можете сделать это: (apply = true '(true false))

person Fei Meng    schedule 21.09.2014

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)
person Dhruv    schedule 23.09.2014