在Clojure中包装

时间:2015-10-19 18:46:39

标签: clojure macros

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

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

使用它的一种方法如下所示:

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

我想创建一个接收排序函数的函数,并使用-collection调用。

(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)的错误数量为:main / eval139628 / fn - 139629

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

是否可以使用函数包装这种宏?感谢。

1 个答案:

答案 0 :(得分:3)

事情是with-collection宏扩展为->,因此您的函数应该将coll作为第一个参数。你也可以使用`find函数来遮蔽monger find函数。可能你应该做这样的事情:

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

并将其称为:

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