I’ve been thinking about it and I don’t yet see any clean way to do it using the inheritance model of Scala. For example if I have an algorithm which should work for any monoid (such as fast exponentiation below), then algebraically speaking, since a group is a monoid, then the fast-exponentiation function should also work given a group. And ideally I should be able to pass the additive group of integers, or the finite multiplicative group of integers modulo 13.
def fastExponentiate[T](x:T, n:Int, monoid[T]):T = {
if (n == 0)
monoid.identity
else if (n == 1)
x
else if ( odd?(n))
monoid.op(x,fastExponentiate(x, n-1, monoid))
else { // even
val a = fastExponentiate(x, n/2, monoid)
monoid.op(a, a)
}
}
Another problem/challenge/modeling-question I see is that many of the algebraic structures obey many is-a relationships.
monoid-wikipedia

One would like to implement these relationship using OO inheritance, so that for example if a function needs a quasigroup, I could happily pass it an inverse semigroup, a loop, or a group.
On the other hand in algebra we say that a ring and a semi-ring is a group. But that’s not really the case. A ring (somehow) contains an additive group, and a multiplicative monoid. On the other hand a field IS a commutative ring, but (somehow) has/contains a multiplicative group made up of all its non-zero element with zero coming from the additive group of the commutative ring.
I’m pretty sure someone coming from Haskell would insist that OO inheritance is not the correct model. But then again he would argue that many common OO problems should be solved without inheritance. Since I don’t know Haskell, I would not be able to understand nor dispute such an argument.
I looked at one treatment, Monoids and Semigroups in Scala the author approaches the problem very different than I would. For example, at the end he demonstrates how to implement an object which contains a mapReduce
function.
It is not clear to me how this generalizes in a way which lets me pass a group to the fastExponentiation
function. Or how to write a matrix multiply function (which needs a semi-ring for + and *) in a way that I could also call matrix-multiply with a field which is-a semi-ring.