Reputation: 1246
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
Reputation: 7882
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:
Upvotes: 1