Type classes?


#1

Has anyone found a good way to do type class stuff in Kotlin? I kind of miss that feature from Scala.

Curtis


#2

Do you have a specific example?


#3

For example, let's say I have a trait:

trait ToJson<T> {
  fun toJson(t: T): String
}

Now, I don’t want every class I have that can be converted to JSON to have to extend this trait and implement toJson in the class itself. In my opinion it pollutes the class. So, let’s say I have a class A that can be converted to JSON:

data class A(val a: String)

I don’t want to mix in how to write to JSON into the A class, so somewhere else I have:

object AtoJson : ToJson<A> {
  fun toJson(a: A): String = “a: $a”
}

So, this object describes how to serialize A to JSON without polluting the A class.

Now, in Scala, you can have a type constraint that says there must be an implicit implementation of a type class:

def toJson[T : ToJson](t: T) = implicitly[ToJson[T]].toJson(t)

I don’t have to pass in anything as long as I have an implicit object in scope that is of type ToJson[T].

In Kotlin, I’d have to do something like:

fun <T> toJson(t: T, conv: ToJson<T>) = conv.toJson(t)

since there are no implicits.

I’ve been trying to figure out a better way with extensions classes and haven’t quite got it yet.

Curtis


#4

Hi,

I think the proposed convert operator will almost provide the equivalent of type classes. See the last couple of comments of http://youtrack.jetbrains.com/issueMobile/KT-1752

In the meantime using extension methods will let you separate out logic from the classes if desired but you’ll just have to manually invoke toJson()  at the call sites instead of it being implicit.

Cheers,
Andrew


#5

Yes, I think this specific example is more a feature request for type conversions than for type classes. I made a similar feature request here, but for DSL's, and this would be perfectly addressed by type conversions as well.


#6

Thanks for the link. I hope they implement that feature.