开发者

Clojure multimethod on class OR keyword

Suppose I have this multimethod

(defmulti m (fn [v] [(:type v)]))

(defmethod m [Object] [k] (prn "Object"))

(defmethod m [:mykwd] [k] (prn "mykwd"))

When I call it with subclass of Object, it correctly dispatches to the first implementation:

(m {:type String})
"Object"

With the :mykwd it also works as expected:

(m {:type :mykwd})
"mykwd"

But when I provide another keyword I get an exception:

(m {:type :anotherkwd})
#<CompilerException java.lang.IllegalArgumentException: No method in multimethod 'm'
for dispatch value: [:anotherkwd] (NO_SOURCE_FILE:0)>

How exactly does this dispatch work?

Is it possible to preserve this behavior for class inheritance and still have a "default" implementation that catches all keywords?

EDIT This example is simplistic, but I need it to work with binary functions. My real nee开发者_如何转开发d is below. I don't see how I could apply :default to it.

(defmulti m (fn [arg mp] [(class arg) (:type mp)]))

Then I'm looking for a way to define it for the case when arg is nil and (:type mp) is anything. This works when value for :type is a class, but not for any keyword:

(defmethod m [nil Object] [arg mp] (prn "Whatever"))


There is a default:

(defmethod m :default [x] :oops)

Reference:

Check http://clojure.org/multimethods at the bottom of the page.


Try replacing your :type dispatch with a custom function that returns a default value when :type is nil. Same for class. Then you can dispatch on a vector of keywords. Add the keywords to a hierarchy if you need inherited behavior.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜