0

I am trying to write a multi-method which dispatches based on the types of all the arguments passed to it, but I am struggling to figure out how to write such a distpatch fn.

By that I mean, given:

(defmulti foo (fn [& args] ...)) (defmethod foo String [& args] (println "All strings")) (defmethod foo Long [& args] (println "All longs")) (defmethod foo Number [& args] (println "All numbers")) (defmethod foo :default [& args] (println "Default")) 

Then we would get:

(foo "foo" "bar" "baz") => "All strings" (foo 10 20 30) => "All longs" (foo 0.5 10 2/3) => "All numbers" (foo "foo" 10 #{:a 1 :b 2}) => "Default" 
1
  • The need for the dispatch on Number complicates things because now you're looking for common super types. Is it actually needed? Commented Mar 25, 2018 at 17:40

2 Answers 2

2
(defmulti foo (fn [& args] (into #{} (map class args)))) (defmethod foo #{String} [& args] (println "All strings")) (defmethod foo #{Long} [& args] (println "All longs")) (defmethod foo #{Number} [& args] (println "All numbers")) (defmethod foo :default [& args] (println "Default")) 

Results in:

(foo "foo" "bar" "baz") => "All strings" (foo 10 20 30) => "All longs" (foo 0.5 10 2/3) => "Default" (foo "foo" 10 #{:a 1 :b 2}) => "Default" 

So the Number example doesn't work.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is the dispatcher fn:

(defmulti foo (fn [& args] (let [m (distinct (map type args))] (when (= 1 (count m)) (first m))))) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.