Home > Software engineering >  Still impossible to assign Kotlin generic function to val?
Still impossible to assign Kotlin generic function to val?

Time:05-04

In Kotlin, I can assign a function to a val.

fun intListCat(a: List<Int>, b: List<Int>): List<Int> = a.plus(b)

fun testIntListCat() {
  val f = ::intListCat
  println( f( listOf(1,2), listOf(30,40) ) )
}

But when I make the function generic, then I'm unable to assign it to a val.

fun<T> listCat(a: List<T>, b: List<T>): List<T> = a.plus(b)

fun testListCat() {

   // error: Not enough information to infer type variable T.
   val f1 = ::listCat
   println( f1( listOf(1,2), listOf(30,40) ) )

   // error: Unresolved reference T.
   val f2: (List<T>, List<T>) -> List<T> = ::listCat
   println( f2( listOf(1,2), listOf(30,40) ) )
}

I'm surprised that a minor change to a simple function seems to disqualify it as a higher-order function in Kotlin, which aims to be as functional as possible.

More than two years ago, there was a similar question on a Kotlin community support page. The community couldn't answer it definitively. And the Kotlin team didn't respond.

I was just wondering if anything changed with Kotlin or programmer knowledge since then, to allow a generic function to be assigned to a val in 2022?

I'm running Kotlin 1.6.20 with Java 17.0.2 on macOS 11.3.1.

CodePudding user response:

No this is not possible. For val f1 = ::listCat to work the way you want, f1 would need to be generic too, but local properties cannot be generic.

By specifying the type explicitly and substituting T with an actual type, you can assign ::listCats to a local property:

val f: (List<Int>, List<Int>) -> List<Int> = ::listCat

Though now you cannot pass other types of lists to f, which is probably undesirable.

On the other hand, non-local properties can be generic, but their type parameter must be used in the receiver parameter, which means that the property must be an extension property, so this probably isn't going to be helpful to whatever you are trying to do.

  • Related