Есть ли в Clojure функция, похожая на «andmap»?
-
06-07-2019 - |
Вопрос
Я хочу применить ряд тестов из своего списка и убедиться, что все тесты пройдены.Есть ли в Clojure функция, похожая на «andmap»?
Решение
Вы можете использовать каждые?
:
user=> (every? string? '("hi" 1))
false
Вот документация по каждые?
.
Другие советы
В Clojure 1.3 будет добавлен Every-pred (и связанный с ним some-fn для версии «или»).
clojure.core/inly-pred ([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]))
Принимает набор предикатов и возвращает функцию F, которая возвращает True, если все его составные предикаты возвращают логическое истинное значение против всех своих аргументов, иначе она возвращает false.Обратите внимание, что F является коротким замыканием в том смысле, что он остановит выполнение в первом аргументе, который запускает логический ложный результат по сравнению с исходными предикатами.
Наивная реализация может быть:
(defn Every-pred [& preds] (fn [& args] (каждый?#(каждый?% арг) предс)))
но фактическая реализация будет иметь лучшую производительность.
Я написал andmap
как макрос, который принимает предикаты в качестве аргументов и создает функцию, которая «оборачивает и
вокруг предикатов», т.е.
(andmap integer? odd?)
==>
(fn [x] (and (integer? x)
(odd? x)))
(он не расширяется до точно этого, но расширяется до чего-то эквивалентного этому)
Преимущество этого метода в том, что он сокращает предикаты, чтобы вы могли писать
(every? (andmap integer? odd?) [1 3 "a string"])
без получения исключения времени выполнения, как это было бы с Ответ Артура . Р>
Вот определение и карты
:
(defmacro andmap ([] `(fn [& x#] true)) ([p & ps] `(fn [& x#] (and (apply ~p x#) (apply (andmap ~@ps) x#)))))
Также можно определить andmap
как функцию, которая также замыкается на его предикаты из-за лени:
(defn andmap [& ps] (fn [& x] (every? true? (map (fn [p] (apply p x)) ps))))
Предикаты для andmap могут принимать произвольное количество аргументов, поэтому можно написать
(map (andmap #(and (integer? %1)
(integer? %2))
#(and (odd? %1)
(even? %2))
<)
[1 3 9]
[2 6 "string"])
, который оценивается как (true true false)
.
every?
спросит " возвращает ли эта одна функция true для каждого члена seq " ;, что близко к тому, о чем я думаю, что вы запрашиваете. Улучшение в each?
позволило бы получить список функций и спросить "Все ли эти предикаты верны для каждого члена этого seq".
Вот первая попытка:
(defn andmap? [data tests]
(every? true? (for [d data, f tests]
(f d))))
user> (andmap? '(2 4 8) [even? pos?])
true
user> (andmap? '(2 4 8) [even? odd?])
false