Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic lambda or function value type in Kotlin

Given a function

fun <T> to5(x: T): Int = 5

is it possible to assign it to variable (value) funVal like this ?

val funVal: (T) -> Int = ::to5

without

Unresolved reference: T

error ?

In other words is it possible to somehow tell Kotlin that T in funVal type declaration is a type parameter?

For example like this:

val <T> funVal: (T) -> Int = ::to5

val funVal<T>: (T) -> Int = ::to5

val funVal: <T> (T) -> Int = ::to5

val funVal: ((T) -> Int) <T> = ::to5

Use case

My use case is using currying with generics. Conceptually:

    fun pairStrWithStr(s: String): (String) -> Pair<String, String> = {
        Pair(s, it)
    }

    val pairStrWithAbc: (String) -> Pair<String, String> = pairStrWithStr("abc")

    pairStrWithAbc("xyz") // (abc, xyz)

Making the second argument generic:

fun <T> pairStrWithAny(s: String): (T) -> Pair<String, T> = {
    Pair(s, it)
}

// Compilation ERROR: Unresolved reference: T
val pairAnyWithAbc: (T) -> Pair<String, T> = pairStrWithAny("abc")

Of course I can provide Any as type:

val pairAnyWithAbc: (Any) -> Pair<String, Any> = pairStrWithAny("abc")

But then I lose the type information:

pairAnyWithAbc(5) // Pair<String, Any>

The solution I can think of are:

Wrapping inside generic fun (basically not real currying or high order function usage)

 fun <T> pairAnyWithAbc(t: T) {
        return pairAnyWithAbc(t)
 }

Creating function for each type (no using generics as I would like)

val pairStrWithAbc: (String) -> Pair<String, String> = pairStrWithAny("abc")

val pairIntWithAbc: (Int) -> Pair<String, Int> = pairStrWithAny("abc")
like image 313
ps-aux Avatar asked Sep 08 '25 02:09

ps-aux


1 Answers

Only classes and functions can have generic type parameters in Kotlin. If you really need a property to have a generic type, it has to belong to a class instance that can provide that generic type, like so:

class Foo<T> {
    val funVal: (T) -> Int = ::to5
}

There's more discussion about this here, I just can't flag this as a duplicate because that question doesn't have an accepted answer.

like image 176
zsmb13 Avatar answered Sep 10 '25 03:09

zsmb13