Я думаю, вы просто хотите использовать обычные протоколы вместе с extend-type
:
(defprotocol Fooable
(foo [this]) )
(extend-type java.lang.Long
Fooable
(foo [some-long] (inc some-long)))
(extend-type java.lang.String
Fooable
(foo [any-string] (str any-string "-and-more")))
с результатом:
(foo 3) => 4
(foo "hello") => "hello-and-more"
Может быть возможно использовать макрос, чтобы скрыть имя протокола, используя автогенсим, но я не вижу в этом смысла. Просто игнорируйте имя протокола 'Fooable', и вы получите тот же результат.
Также помните, что части реализации Clojure создают конкретные классы Java за кулисами, для которых может потребоваться жестко запрограммированное имя.
Вы также можете имитировать функциональность протокола, используя cond
:
(defn bar [it]
(cond
(= (class it) java.lang.Long) (inc it)
(= (class it) java.lang.String) (str it "-and-more")))
(bar 7) => 8
(bar "farewell") => "farewell-and-more"
Вы можете определить функцию для генерации bar
, как вы делаете с polymorphic-fn
, если хотите.