Hi,
this proposal follow the typeclass on Kotlin.
The class kotlin.reflect.KClass
can become a typeclass, ie:
typeclass KClass<T : Any>
For each exsisting type T
the Kotlin compiler is already able to define a specific instance of KClass<T>
, currenlty it is expressed as T::class
.
The goal is to mimic a reified type without requiring the inlining.
A simple example is:
class TypePredicate<T> : Predicate<T> given KClass<T> {
override fun filter(e : T) = e is T
}
val stringTypePredicate : Predicate<String> = TypePredicate()
I prepared a litte proof of concept for JVM, I reimplemented some reified function using typeclass.
Before each typeclass version a comment explain a possible syntax.
sealed class Shape
data class Box(val side: Int) : Shape()
data class Circle(val radius: Int) : Shape()
fun main(args: Array<String>) {
val list: List<Shape> = listOf(Box(1), Circle(2), Box(3), Circle(4))
println("ir typeOf " + typeOf(list))
println("tc typeOf " + typeOf(list, List::class))
println("ir filterInstance " + list.filterInstance<Shape, Box>())
println("tc filterInstance " + list.filterInstance<Shape, Box>(Box::class))
println("ir newArray " + newArray<String>(3))
println("tc newArray " + newArray(3, String::class))
}
inline fun <reified T : Any> typeOf(e: T) = T::class
// fun <T> typeOf() given KClass<T> = T::class
fun <T : Any> typeOf(e: T, t: KClass<T>) = t
inline fun <I : Any, reified O : I> List<I>.filterInstance(): List<O> =
filter { it is O } as List<O>
// fun <I:Any, O: I> List<I>.filterInstance() given KClass<O> = filter { it is O } as List<O>
fun <I : Any, O : I> List<I>.filterInstance(o: KClass<O>): List<O> =
filter { o.java.isInstance(it) } as List<O>
inline fun <reified T : Any> newArray(length: Int) = arrayOfNulls<T>(length)
// fun <T : Any> newArray(length: Int) given KClass<T> = arrayOfNulls<T>(length)
fun <T : Any> newArray(length: Int, t: KClass<T>) =
java.lang.reflect.Array.newInstance(t.java, length)
The above code is a simple POC.
For various reasons I not consider the type class as a replacement of reified parameter.