"Extension types" for Kotlin

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"

It has similar structure to delegation and doesn’t require a type parameter on the interface, plus no new keywords.

I don’t see how IMonoid for String achieves something different to IMonoid<String>. Why not use the syntax that is already available in the languag?

It doesn’t require modifying the interface itself. Sometimes the target interface is a third-party as well, Android’s Parcelable is an example.

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

1 Like