2014-09-25 64 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