Я не уверен, какова практическая цель этого вопроса, но это интересно с академической точки зрения.
Ключевое слово "function" :b
в следующем является функцией 1аргумент:
(:b {:a 1 :b 2}) => 2
Это похоже на эту функцию:
(defn get-b [m] (get m :b)) ; takes a single map arg
(get-b {:a 3 :b 33}) ; only 1 arg, so no problem
=> 33
Специальная форма apply
переписывает вызов функции от наличия одного аргумента коллекции до нескольких отдельных аргументов.Сравнивая до и после, мы получаем:
(apply some-fn [1 2 3] ) ; using apply
(some-fn 1 2 3 ) ; without apply (note missing square brackets!)
Итак, apply
позволяет вам «распространять» аргументы из коллекции , как если бы вы ввели их какотдельные, отдельные аргументы в вызове функции.Если ваша коллекция содержит только 1 элемент, использование apply имеет небольшой эффект:
(apply :b [{:a 3 :b 33}] ) ; a collection of 1 element
(:b {:a 3 :b 33} ) ; only 1 arg, so no problem
Поскольку функция: b занимает всего 1 аргумент, следующее не будет работать:
(apply #(:b %) [{:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]) ; takes only 1 arg, not 3 args
ОднакоВы можете вызывать функцию 1-arg :b
несколько раз, используя map
или mapv
:
(mapv :b [{:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]) ; takes only 1 arg, not 3 args
=> [11 22 33]
Те же правила действуют в обратном случае.Карта типа {:a 1 :b 2}
является функцией с 1 аргументом, поэтому ее нельзя вызывать с 3 аргументами:
(apply {:a 1, :b 2, :c 3} [:c :b :a]) ; 3 args to single-arg fn, so fails
, но это прекрасно работает:
(mapv {:a 1, :b 2, :c 3} [:c :b :a]) => [3 2 1]