Monoids in Clojure
(defn semigroup [append]
{::append append})
(defn monoid [semigroup empty]
(assoc semigroup ::empty empty))
(defn append [semigroup a b]
((::append semigroup) a b))
(defn concat [monoid xs]
(reduce (::append monoid) (::empty monoid) xs))
(def semigroup-add
(semigroup +))
(def monoid-add
(monoid semigroup-add 0))
(prn (concat monoid-add [1 2 3]))
INFO