rtsketo
rtsketo

Reputation: 1246

Distinguish functions with lambda argument by lambda's return type?

I have a function timeout(...) (extension function that returns this) which accepts an argument that is either String, Date or Long. What I am trying to do is to make it accept any lambda that also returns one of these three types.

Kotlin finds the below functions ambiguous and can't decide which one to call when I type, for example, timeout { "something" }.

@JvmName("timeoutString")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->String): CR = timeout(timeLambda())

@JvmName("timeoutLong")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->Long): CR = timeout(timeLambda())

@JvmName("timeoutDate")
fun <CR: CachableResponse> CR.timeout(timeLambda: CR.()->Date): CR = timeout(timeLambda())

The error I'm getting is Cannot choose among the following candidates without completing type inference.

Of course one way to work around this, is to have one function instead of three like this:

fun <CR: CachableResponse, Type> CR.timeout(timeLambda: CR.()->Type): CR =
        timeLambda().let { when (it) {
            is String -> timeout(it)
            is Date -> timeout(it)
            is Long -> timeout(it)
            else -> this
        } }

In this case, though, the developer won't have any clue what its lambda will have to return without reading the description or checking the source code.

Is there any more elegant solution?

Upvotes: 0

Views: 83

Answers (1)

Actually, you solution is rather elegant. I would only suggest to inline CR generic parameter and capture when subject in a variable:

fun <Type> CachableResponse.timeout(timeLambda: CachableResponse.() -> Type) =
    when (val it = timeLambda()) {
        is String -> timeout(it)
        is Date -> timeout(it)
        is Long -> timeout(it)
        else -> this
    }

In this case, though, the developer won't have any clue what its lambda will have to return without reading the description or checking the source code.

IDE comes to the rescue:

enter image description here enter image description here

Upvotes: 1

Related Questions