2015-10-19 37 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))