为什么 - >不服用(fn ......)?

时间:2012-01-11 06:45:12

标签: clojure

我有以下代码可以使用:

(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)>

任何人都可以向我解释这个吗?

我试图解决的问题是map和filter将集合作为最后一个参数,但str/partition将集合作为第一个参数,所以我试图使用{{ 1}}但是将->map合并到只接受集合的一个(第一个)参数的函数中。

3 个答案:

答案 0 :(得分:3)

您可以将->->>混合到一定程度。

(-> 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 %)))

答案 1 :(得分:2)

您正在使用函数声明作为函数调用。修复它的直接(丑陋)方法是用((fn [...] ...)替换(fn [...] ..)

答案 2 :(得分:1)

- &GT;是一个宏。它操纵你给它的代码,然后执行该代码。当您尝试使用内联类似的匿名函数时会发生什么,以前的表达式是作为fn的第一个参数进行线程化的。那不是你想要的。您希望它们作为实际函数的第一个参数进行线程化。

要使用 - &gt;,您必须事先声明这些功能,就像您在第一个示例中所做的那样。