Clojure线程第一个宏 - >使用Math / pow或任何其他多个args函数

时间:2015-04-27 13:25:20

标签: clojure macros

如何在一行中写下以下代码:

SELECT g.SECTION_ID,
       g.NUMERIC_GRADE, 
       s.First_Name,
       s.Last_Name
  FROM grade g 
  JOIN Student s
    ON g.student_ID = s.student_ID
   AND Grade_Type_Code='MT'
 WHERE numeric_grade in (SELECT numeric_grade
                           FROM (SELECT DISTINCT numeric_grade
                                   FROM grade 
                               ORDER BY numeric_grade desc)
                   WHERE ROWNUM <=3);

其中pow9是:

(-> 10 pow9)

如果我写(def pow9 (partial #(Math/pow % 9))) ,我会回来(-> 10 (partial #(Math/pow % 9))), 使用#<core$partial$fn__4228 clojure.core$partial$fn__4228@62330c23>

撰写(-> 10 #(Math/pow % 9))失败

尽管CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.ISeq, compiling:(NO_SOURCE_PATH:1:1)工作正常。

更一般的问题是如何使用 - &gt;使用接受多个参数的函数,即如何使其工作(-> 10 pow9)

3 个答案:

答案 0 :(得分:5)

->将以前的结果作为第一个参数插入,->>将之前的结果作为最后一个参数插入。

user=> (-> 10 (Math/pow 9))
1.0E9

user=> (-> 10 ((partial #(Math/pow % 9))))
1.0E9

注意额外的parens。

实际上,你根本不需要部分:

user=> (defn pow9 [x] (Math/pow x 9))
#'user/pow9
user=> (-> 10 pow9)
1.0E9

答案 1 :(得分:2)

电话只是

user=> (-> 10 (Math/pow 9))
1.0E9

因为->线程宏将结果作为第一个参数发送。

答案 2 :(得分:1)

如果你想用线程项作为参数来调用匿名函数,你需要另外一组parens:

 (-> 10 (#(Math/pow % 9)))

这是因为宏在函数定义(或部分应用程序,或者您正在做的任何事情)之前插入项目进行评估。