Makes sense, for the regular class part, we could use this syntax:
class StringMonoid : IMonoid for String {
override fun zero() = ""
override fun append(other: String) = this + other
}
fun doMonoidStuff(m: IMonoid) {
...
}
fun main() {
private companion val stringMonoid = StringMonoid()
val someString = "hi world"
doMonoidStuff(someString)
}
It has similar structure to delegation and doesn’t require a type parameter on the interface, plus no new keywords.
It seems to me that as long as you are fine with EXPLICIT vs. implicit then you can basically do it now like this:
val String.monoid get() = object : Monoid<String> {
override fun zero() = ""
override fun append( a1: String, a2: String) = a1 + a2
}
Then you can just do MyString.monoid to explicitly convert to a monoid.
If you want implicit conversion aren’t you then moving to morass of implicit conversion that lead IntelliJ to reject Scala and create Kotlin to begin with?
Just a small tip for people who are interested in this. Check out the proofs plugin based on Arrow Meta that basically allows well-founded implicit conversion while avoiding the mess of Scala’s implicits. You can basically think of it as projecting new syntax and functions onto an already existing type. They achieve that performantly using inline classes so that it has almost no overhead