Почему -> не принимает (фн ...)? - PullRequest
0 голосов
/ 11 января 2012

У меня есть следующий код, который работает:

(def *primes*
  (let [l "2 3 5 7 11 13 17 19 23 29 31"
        f (fn [lst] (filter #(< 0 (count (str/trim %))) lst))
        m (fn [lst] (map #(Integer/parseInt %) lst))]
    (-> l
      (str/partition #"[0-9]+")
      f
      m)))

Если я изменю его на встроенный фильтр (f) и сопоставим функции (m) с этим:

(def *primes*
  (let [l "2 3 5 7 11 13 17 19 23 29 31"]
    (-> l
      (str/partition #"[0-9]+")
      (fn [lst] (filter #(< 0 (count (str/trim %))) lst))
      (fn [lst] (map #(Integer/parseInt %) lst)))))

больше не компилируется. Ошибка:

#<CompilerException java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol (NO_SOURCE_FILE:227)>

Может кто-нибудь объяснить мне это?

Проблема, которую я пытаюсь решить, состоит в том, что карта и фильтр принимают коллекцию в качестве последнего параметра, но str/partition принимает коллекцию в качестве первого, поэтому я пытаюсь смешать два, используя -> вставка map и filter в функции, которые принимают только один (первый) параметр для входа в коллекцию.

Ответы [ 3 ]

3 голосов
/ 11 января 2012

Вы можете смешивать -> и ->> до определенной степени.

(-> l
  (str/partition #"[0-9]+")
  (->> (filter #(< 0 (count (str/trim %)))))
  (->> (map #(Integer/parseInt %))))

Но обычно такие проблемы являются признаком того, что вы пытаетесь сделать слишком много в одной форме. Этот простой пример может быть легко исправлен.

(->> (str/partition l #"[0-9]+")
  (filter #(< 0 (count (str/trim %))))
  (map #(Integer/parseInt %)))
2 голосов
/ 11 января 2012

Вы используете объявления функций в качестве вызовов функций.немедленный (некрасивый) способ исправить это заменить (fn [..] ..) на ((fn [..] ...))

1 голос
/ 23 января 2012

-> это макрос.Он манипулирует кодом, который вы ему даете, и затем выполняет этот код.То, что происходит, когда вы пытаетесь использовать анонимные встроенные функции подобным образом, заключается в том, что предыдущие выражения добавляются в качестве первого аргумента для fn.Это не то, что вы хотите.Вы хотите, чтобы они были добавлены в качестве первого аргумента к действительной функции.

Чтобы использовать ->, вам необходимо объявить функции заранее, как вы это делали в первом примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...