2014-09-25 52 views
0

我的工作problem #74在4clojure.com,我的解决方法是如下:Clojure的:“线程优先”宏观 - >和“线程最后一个”宏观 - >>

(defn FPS [s] 
    (->> 
    (map read-string (re-seq #"[0-9]+" s)) 
    (filter #(= (Math/sqrt %) (Math/floor (Math/sqrt %)))) 
    (interpose ",") 
    (apply str))) 

它工作得很好。但如果我使用了“线程优先”宏观 - >

(defn FPS [s] 
    (-> 
    (map read-string (re-seq #"[0-9]+" s)) 
    (filter #(= (Math/sqrt %) (Math/floor (Math/sqrt %)))) 
    (interpose ",") 
    (apply str))) 

,则返回:ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:617)

为什么“ - >>”“ - >”在这个问题不能被取代?

回答

7

在Clojure中REPL:

user=> (doc ->) 
------------------------- 
clojure.core/-> 
([x & forms]) 
Macro 
Threads the expr through the forms. Inserts x as the 
second item in the first form, making a list of it if it is not a 
list already. If there are more forms, inserts the first form as the 


user=> (doc ->>) 
------------------------- 
clojure.core/->> 
([x & forms]) 
    Macro 
    Threads the expr through the forms. Inserts x as the 
    last item in the first form, making a list of it if it is not a 
    list already. If there are more forms, inserts the first form as the 
    last item in second form, etc. 

filter函数要求第一个参数是一个函数,而不是一个序列,并通过使用S- ->,你没有满足其要求。

这就是为什么你的代码中出现clojure.lang.LazySeq cannot be cast to clojure.lang.IFn异常。

7

最后一个宏(->>)插入每个作为下一个表单的最后一个元素。线程优先宏(->)将它作为第二个元素插入。

所以,这样的:

(->> a 
    (b 1) 
    (c 2)) 

翻译为:(c 2 (b 1 a)),而

(-> a 
    (b 1) 
    (c 2)) 

翻译为:(c (b a 1) 2)

+0

' - >'插入第二个位置,而不是第一个。 – Chiron 2014-09-25 09:24:00

+0

对。纠正... – Tomo 2014-09-25 09:59:45