I have a simple factory pattern where the implementation is determined through overload resolution. Problem is that the Kotlin compiler complains with "Overload resolution ambiguity.." for the inline lambda.
class Foo(){
companion object Factory {
fun create(x: Int, f: (Int) -> Double) = 2.0
fun create(x: Int, f: (Int) -> Int) = 1
}
}
fun main(args:Array<String>){
val a = Foo.create(1,::fromDouble) //OK
val b = Foo.create(1,::fromInt) //OK
val ambiguous = Foo.create(1){i -> 1.0} //Overload resolution ambiguity?
}
fun fromDouble(int:Int) = 1.0
fun fromInt(int:Int) = 1
How does the Kotlin compiler resolve overload resolution and why is the inline lambda considered to be ambiguous?
Kotlin compiler resolves every expression only once.
So when compiler starts resolution for lambda expression, it should know types of lambda arguments.
Because of this compiler should choose one of methods create
before it starts to look inside lambda.
Example:
fun foo(f: (Int) -> Int) = 1
fun foo(f: (String) -> String) = ""
val bar = foo {
println(it)
5
}
Here we can't choose one of functions foo
because no one of them is more specific that another, so we can't start resolution for lambda expression because we don't know type for it
.
In your example it is in theory possible to start resolution for lambda before choosing particular function because for all potential functions types of lambda arguments are the same. But it is untrivial logic which might be hard to implement.
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