I have a method with two type parameters, only one of which can be inferred from arguments, something like (no need to comment this cast is evil, the body is purely for the sake of example)
fun <A, B> foo(x: Any, y: A.() -> B) = (x as A).y()
// at call site
foo<String, Int>("1", { toInt() })
However, the compiler can tell B
is Int
if A
is String
. And more generally, if it knows A
, B
can be inferred.
Is there a way to only provide A
at the call site and infer B
?
Of course, the standard Scala approach works:
class <A> Foo() {
fun <B> apply(x: Any, y: A.() -> B) = ...
}
// at call site
Foo<String>().apply("1", { toInt() })
I was interested in whether Kotlin has a more direct solution.
Based on this issue/proposal, I'd say no(t yet):
Hello, I am proposing two new feature for kotlin which go hand in hand: partial type parameter list and default type parameters :) Which in essence allows to do something as the following:
data class Test<out T>(val value: T) inline fun <T: Any, reified TSub: T> Test<T>.narrow(): Test<TSub>{ return if(value is TSub) Test(value as TSub) else throw ClassCastException("...") } fun foo() { val i: Any = 1 Test(i).narrow<_, Int>() // the _ means let Kotlin infer the first type parameter // Today I need to repeat the obvious: Test(i).narrow<Any, Int>() }
It would be even nicer, if we can define something like:
inline fun <default T: Any, reified TSub: T> Test<T>.narrow(): Test<TSub>{ return if(value is TSub) Test(value as TSub) else throw ClassCastException("...") }
And then don't even have to write
_
fun foo() { val i: Any = 1 Test(i).narrow<Int>() //default type parameter, let Kotlin infer the first type parameter }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With