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.