Clojure:"线程优先"宏 - >和"线程最后"宏 - >>

时间:2014-09-25 08:55:22

标签: clojure

我正在4clojure.com上problem #74工作,我的解决方案如下:

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

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

2 个答案:

答案 0 :(得分:7)

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

所以,这个:

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

转换为:(c 2 (b 1 a)),而

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

转换为:(c (b a 1) 2)

答案 1 :(得分: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异常的原因。