我有以下代码可以使用:
(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
合并到只接受集合的一个(第一个)参数的函数中。
答案 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;,您必须事先声明这些功能,就像您在第一个示例中所做的那样。