Странная ошибка при попытке сопоставить parseInt в Clojure

Я изучаю Clojure, и у меня есть сомнения:

Почему при вводе

(map vector '("1" "2" "3"))

Я получаю (["1"] ["2"] ["3"])

Это нормально, потому что vector - это функция (или почти я думаю), и я могу сделать (vector "3") и получите ["3"].

Пока все хорошо, но когда я пытаюсь

(map Integer/parseInt '("1" "2" "3"))

Я получаю сообщение об ошибке. Не следует ли parseInt вести себя как функция?

Затем мне нужно ввести

(map #(Integer/parseInt %) '(......

Почему я не могу использовать parseInt как функцию? Для меня это функция, и я могу использовать ее как

(Integer/parseInt "3")

Я чувствую, что это немного некогерентно, но я уверен, что ошибаюсь, и для этого я прошу...

Ответ 1

Вы должны обернуть его в #() или (fn ...). Это связано с тем, что Integer/parseInt - это метод Java, и методы Java не могут быть переданы. Они не реализуют интерфейс IFn.

Clojure построен на Java, и иногда это протекает, и это один из этих случаев.

Ответ 2

Как утверждали другие, вам нужно обернуть Integer/parseInt, чтобы преобразовать его из Java-метода в функцию Clojure:

(map #(Integer/parseInt %) '("1" "2" "3"))

Причиной этого является то, что функции Clojure должны реализовывать интерфейс IFn для передачи в качестве аргументов в функции более высокого порядка, такие как map.

Это немного уродливо, если вы делаете такое преобразование много раз, поэтому я бы рекомендовал обернуть вашу функцию parse-int следующим образом:

(defn parse-int [s] (Integer/parseInt s))

(map parse-int '("1" "2" "3"))

В качестве окончательной альтернативы вы можете использовать встроенную функцию read-string - это вернет целые числа в вашем случае, но также будет работать и для удвоений и т.д.:

(map read-string '("1" "2" "3"))