问题
The following does not work, for obvious reasons.
(defprotocol Monoid
(mappend [a b])
(mzero []))
mzero
has zero arguments, and zero argument methods are not allowed (or do not make sense) in protocols. In Haskell or Scala, where the dispatch is type-based rather than value-based, this is not a problem.
What would be the correct way to conceptualize and write Monoid
protocol in Clojure?
回答1:
looking at the source, the way that this is implemented in the new reducers library is not as a procotol but an overloaded function. a no-args call is mzero; two args call is mappend.
more exactly, monoid
takes two arguments - op
and ctor
and returns a function which, when called with no arguments, evaluates ctor
, and when called with two, delegates to op
.
this is consistent with how zero is handled in a fold, for example - reduce
(fold) will evaluate the function being folded with no args to find the zero, if necessary.
i feel a bit ashamed to show something so unexciting, but i don't see how you can do better within clojure. thanks for the explanations/education in the comments.
来源:https://stackoverflow.com/questions/10767793/how-to-write-monoid-protocol-in-clojure