作为一个例子,我们希望能够在类型为OrderedCollection[Monoid]的实体上定义sum。这里的 Monoid 是一个带有零元的可结合操作的特质/接口。然后我们就不需要再复制和粘贴sum代码来使用它了。但是,一个类型可以以多种方式成为单子:例如,正整数可以使用加号和0或者乘号和1。我不能想出一个很好的处理方法。
Haskell有一个很好的技巧,使用newtype
语言特性来处理许多单子的情况:
http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html(从“相同的类型可以以不同的方式产生单子”开始阅读)
http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-Monoid.html#3(关于数字加法和乘法单子的官方文档)。
你肯定需要明确你想使用哪个操作符吧?我不认为有任何明智的方法可以避免这个问题。
在Clojure中,我会使用高阶函数:
(defn sum-with [op]
(fn [coll]
(reduce op coll)))
然后你可以这样做:
(def sum1 (sum-with +))
(sum1 [1 2 3 4])
=> 10
(def sum2 (sum-with *))
(sum2 [1 2 3 4])
=> 24