用 Clojure 包装
Posted
技术标签:
【中文标题】用 Clojure 包装【英文标题】:Wrapping in Clojure 【发布时间】:2016-01-18 05:29:31 【问题描述】:有时我很难在 Clojure 中包装函数或宏。
例如,Clojure Mongo 提供了一个 DSL 来查询集合:with-collection,这是一个宏。
一种使用方式如下所示:
(with-collection db coll
(find )
(sort (array-map :score -1 :name 1)))
我想创建一个接收排序函数并调用 with-collection 的函数。
(defn find [sort]
(with-collection my-db my-coll
(find )
sort
)
如果我尝试调用该函数,我会收到以下错误:ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
(find (sort (array-map :score -1 :name 1))
我猜这是因为正在评估 sort 并且 with-collection 需要一个函数。
如果我尝试引用,则会收到以下错误:ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
(find (quote sort (array-map :score -1 :name 1)))
如果我尝试传递匿名函数,我会收到以下错误:ArityException Wrong number of args (1) passed to: main/eval139628/fn--139629
(find #(sort (array-map :score -1 :name 1))
是否可以使用函数来包装这种宏?谢谢。
【问题讨论】:
您的匿名函数不接受任何参数。试试#(sort % (array-map :score -1 :name 1))
【参考方案1】:
问题是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))
【讨论】:
以上是关于用 Clojure 包装的主要内容,如果未能解决你的问题,请参考以下文章