Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling overloaded method of Kotlin in Scala

Tags:

kotlin

scala

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])?

like image 542
Hoshino Tented Avatar asked May 09 '20 19:05

Hoshino Tented


People also ask

Can you overload methods in Scala?

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.

Does Kotlin support overloading?

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.


Video Answer


1 Answers

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.

like image 67
Dmytro Mitin Avatar answered Sep 30 '22 11:09

Dmytro Mitin