I don't know how to specify a function literal where the input parameter can covary so that the function literal can have assigned to it functions that accept subtypes of the input type.
The simplest example I can come up with is that i want to do something like this:
var f: (Number) -> Unit = { number: Number -> println(number) } f = {int: Int -> println(number) } // <-- this does not compile These declarations do not work:
var f: (in Number) -> Unit = {number: Number ->} // doesn't compile var f: (out Number) -> Unit = {number: Number ->} // doesn't compile var f: <N: Number> (N) -> Unit = {number: Number ->} // ridiculous Here is the context of what I ACTUALLY want to do. I want to create a simple event handler class.
This is my Kotlin code:
class EventHandler() { private val NO_OP = {event: Event -> } private val handlerMap = mutableMapOf<KClass<out Event>, (Event) -> Unit>() // here is the problem declaration fun <E: Event> registerHandler( eventClass: KClass<out E>, handler: (E) -> Unit) { handlerMap[eventClass] = handler // this doesn't compile } fun handle(event: Event) = getHandler(event).invoke(event) fun getHandler(event: Event): (Event) -> Unit = handlerMap[event::class] ?: NO_OP } The handlerMap[eventClass] = handler doesn't compile, because the handlerMap accepts as values (Event) -> Unit, and the type of the handler is (E) -> Unit where E is a type parameter that extends Event (<E: Event>).
The Error message is:
Events.kt:[18,9] Type inference failed: Cannot infer type parameter V in operator inline fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit None of the following substitutions receiver: MutableMap<KClass<out Event>, (Event) -> Unit> arguments: (KClass<out Event>,(Event) -> Unit) receiver: MutableMap<KClass<out Event>, (E) -> Unit> arguments: (KClass<out Event>,(E) -> Unit) can be applied to receiver: MutableMap<KClass<out Event>, (Event) -> Unit> arguments: (KClass<out E>,(E) -> Unit) I am using kotlin-maven-plugin:1.1-M03.
inorout, and without casting. Otherwise you are doing something wrong and it can fail at runtime.