Допустим, у меня есть несколько векторов
(def coll-a [{:name "foo"} ...])
(def coll-b [{:name "foo"} ...])
(def coll-c [{:name "foo"} ...])
, и я хотел бы видеть, равны ли имена первых элементов.
Я мог бы
(= (:name (first coll-a)) (:name (first coll-b)) (:name (first coll-c)))
, но это быстро становится утомительным и слишком многословным, так как составляется все больше функций.(Может быть, я хочу сравнить последнюю букву имени первого элемента?)
Чтобы напрямую выразить суть вычислений, кажется интуитивно понятным
(apply = (map (comp :name first) [coll-a coll-b coll-c]))
, но это заставляет меня задуматься, есть лиабстракция более высокого уровня для такого рода вещей.
Я часто нахожу себя сравнивающим / иным образом работающим с вещами, которые должны быть вычислены с помощью одной композиции, примененной к нескольким элементам, но синтаксис карты выглядит мне немного не по вкусу.
Если бы я былдля домашнего приготовления какого-то оператора, я бы хотел синтаксис, такой как
(-op- (= :name first) coll-a coll-b coll-c)
, потому что большая часть вычислений выражается в (= :name first)
.
Я хотел бы применить абстракцию ки оператор, и функции, применяемые к каждому аргументу.То есть сумма должна быть такой же простой, как и сумма сравнения.
(def coll-a [{:name "foo" :age 43}])
(def coll-b [{:name "foo" :age 35}])
(def coll-c [{:name "foo" :age 28}])
(-op- (+ :age first) coll-a coll-b coll-c)
; => 106
(-op- (= :name first) coll-a coll-b coll-c)
; => true
Что-то вроде
(defmacro -op-
[[op & to-comp] & args]
(let [args' (map (fn [a] `((comp ~@to-comp) ~a)) args)]
`(~op ~@args')))
- Есть ли идиоматический способ сделать это в укорачивании, какой-то стандартныйбиблиотечную функцию, которую я мог бы использовать?
- Есть ли имя для этого типа выражения?