Here are two functions, one in kotlin.kt
:
interface TraitA
fun <T : TraitA> foo(a: Any, f: (T) -> Unit) {
TODO()
}
another adapter function in Scala.scala
import KotlinKt.foo
object Scala {
def adapter[E <: TraitA](f: (E) => Unit): Unit = {
foo[E](None, { a =>
// Do something
kotlin.Unit.INSTANCE
})
}
}
Till this moment, it compiles. But when I overload this function in Kotlin:
interface TraitA
fun <T : TraitA> foo(f: (T) -> Unit) {
TODO()
}
fun <T : TraitA> foo(a: Any, f: (T) -> Unit) {
TODO()
}
Scala fails to compile with the following error:
> Task :scala:compileScala
[Error] E:\Documents\Projects\Temp\kotlin-example\scala\src\main\scala\Scala.scala:5: missing parameter type
one error found
It tells me to add parameter type, so I added it:
import KotlinKt.foo
object Scala {
def adapter[E <: TraitA](f: (E) => Unit): Unit = {
foo[E](None, { (a: E) =>
kotlin.Unit.INSTANCE
})
}
}
The compiler throws other error after the change:
[Error] E:\Documents\Projects\Temp\kotlin-example\scala\src\main\scala\Scala.scala:5: overloaded method foo with alternatives:
(x$1: Object,x$2: kotlin.jvm.functions.Function1[_ >: E, kotlin.Unit])Unit <and>
(x$1: kotlin.jvm.functions.Function1[_ >: E, kotlin.Unit])Unit
cannot be applied to (None.type, E => kotlin.Unit)
one error found
I tried to construct a Kotlin Function1
"explicitly":
import KotlinKt.foo
import kotlin.jvm.functions.{Function1 => KF1}
object Scala {
def adapter[E <: TraitA](f: (E) => Unit): Unit = {
val kf: KF1[E, kotlin.Unit] = { e => f(e); kotlin.Unit.INSTANCE }
foo[E](None, kf)
}
}
It compiles and works well. But it is too circuitous, is there a prettier way to call foo[T](Any, Function1[_ >: T, kotlin.Unit])
?
Method Overloading is the common way of implementing polymorphism. It is the ability to redefine a function in more than one form. A user can implement function overloading by defining two or more functions in a class sharing the same name.
Kotlin supports overloading for callables and properties, that is, the ability for several callables (functions or function-like properties) or properties with the same name to coexist in the same scope, with the compiler picking the most suitable one when such entity is referenced.
Try to add implicit conversion
implicit def scalaToKotlin(u: Unit): kotlin.Unit = kotlin.Unit.INSTANCE
Then
def adapter[E <: TraitA](f: (E) => Unit): Unit = {
foo(None, (e: E) => f(e))
}
compiles.
Scala 2.13.2, Kotlin 1.3.50, sbt 1.3.8 + kotlin-plugin 2.0.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With