2015-10-19 57 views
3

有时我很难在Clojure中包装函数或宏。在Clojure中包装

例如Clojure Mongo提供了一个DSL来查询集合:with-collection,这是一个宏。下面用它

一种方式显示:

(with-collection db coll 
    (find {}) 
    (sort (array-map :score -1 :name 1))) 

我想创建一个接收排序功能,并与收集调用一个函数。

(defn find [sort] 
    (with-collection my-db my-coll 
     (find {}) 
     sort 
) 

如果我尝试调用该函数,我得到了以下错误:ClassCastException异常clojure.lang.PersistentList不能转换到clojure.lang.IFn

(find (sort (array-map :score -1 :name 1)) 

我想这是因为排序正在评估with-collection需要一个函数。

如果我试图引用我得到以下错误:ClassCastException异常clojure.lang.PersistentList不能转换到clojure.lang.IFn

(find (quote sort (array-map :score -1 :name 1))) 

如果我试图通过一个匿名函数,我得到以下错误:ArityException数错误ARGS(1)传递给:主/ eval139628/FN - 139629

(find #(sort (array-map :score -1 :name 1)) 

是否有可能来包装这种宏观使用的功能呢?谢谢。

+1

您的匿名函数不带任何参数。尝试'#(sort%(array-map:score -1:name 1))' –

回答

3

事情是with-collection宏扩展为->,所以你的函数应该有coll作为第一个参数。你也可以用你的find函数来影响这个牌手find函数。也许你应该做这样的事情:

(defn my-find [sort] 
    (with-collection my-db my-coll 
    (find {}) 
    sort) 

,并调用它像这样:

(my-find #(sort % (array-map :score -1 :name 1))