Clojureのdefmultiでポリモーフィズム

関数型デザイン【委託】 - 達人出版会

こちらの9章から。

Clojureにおけるポリモーフィズムの話が出てきたが、 それは defmultidefmethod で実現できるらしい。

一見すると defmultiの挙動が全然わからんかったので、書いておく。

defmulti

defmulti - clojure.core | ClojureDocs - Community-Powered Clojure Documentation and Examples

;  マルチメソッド calcを定義
; calcを実行するときに :typeキーワードでgetする
; (defmulti calc (fn [x] (get x :type))) と同義
(defmulti calc :type)

; calcの引数に渡った:typeが:addなら、この関数を実行
(defmethod calc :add [params]
  (+ (:a params) (:b params)))

; calcの引数に渡った:typeが:subなら、この関数を実行
(defmethod calc :sub [params]
  (- (:a params) (:b params)))

; calcの引数に渡った:typeが:mulなら、この関数を実行
(defmethod calc :mul [params]
  (* (:a params) (:b params)))

; calcの引数に渡った:typeが:divなら、この関数を実行
(defmethod calc :div [params]
  (/ (:a params) (:b params)))

(calc {:type :add :a 1 :b 2}) ; 3
(calc {:type :sub :a 1 :b 2}) ; -1
(calc {:type :mul :a 1 :b 2}) ; 2
(calc {:type :div :a 1 :b 2})  ; 1/2

最初は難しいなと思ったけど慣れたらいけるかもしれない。