Есть ли в Clojure функция, похожая на «andmap»?

StackOverflow https://stackoverflow.com/questions/1209824

  •  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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top