I was hoping Scala.js would be able to ignore ambiguous overloads for native JS traits since they have JavaScript semantics and in JavaScript there are no overloads. This isn’t possible since Scala.js is using the normal Scala type system. (See https://github.com/scala-js/scala-js/issues/4709)
I was wondering whether it would be possible for Scala to pick the overload for the type which is more specific?
So in this case:
object Main extends App {
trait Bar
trait Baz
def foo(bar: Bar): String = "bar"
def foo(bar: Baz): Int = 123
object BarBaz extends Bar with Baz
foo(BarBaz)
}
It would pick the second foo
since Baz
comes earlier in linearization.
If you want the other one then you would add the type ascription of Bar
.
I had hoped to work around this by using implicit priorities but even that doesn’t work. For example:
import scala.language.implicitConversions
object Main2 extends App {
trait Bar
trait Baz
def foo(bar: Bar): String = "bar"
def foo(bar: Baz): Int = 123
object BarBazImplicit extends LowerPriorityImplicit {
implicit def toBar(me: BarBazImplicit.type): Bar = new Bar {}
}
trait LowerPriorityImplicit {
implicit def toBaz(me: BarBazImplicit.type): Baz = new Baz {}
}
foo(BarBazImplicit)
}
This is easy in the case that there is only a single parameter but if there are two then it might still be ambiguous:
object Main3 extends App {
trait Bar
trait Baz
def foo(bar: Bar, baz: Baz): String = "bar"
def foo(baz: Baz, bar: Bar): Int = 123
object BarBaz extends Bar with Baz
foo(BarBaz, BarBaz)
}
This could either still be an error and be what you want in the majority of cases or it could look at the parameters from left to right until it finds one that is more specific.