During daily Scala coding I faced an issue that Scala implicits resolution depends on declaration order. A simple example:
object example extends App {
trait FooTypeClass[T] {
def foo: T
}
def bar[T](implicit tc: FooTypeClass[T]) = println(tc.foo)
class A {
// bar[A] doesn't compile
}
object A {
implicit object aFoo extends FooTypeClass[A] {
def foo: A = new A { override def toString = "a" }
}
}
bar[A]
}
It does compile, but if I uncomment the commented line, it won't find the required implicit in scope. So, to make it compile I should place object A
declaration before class A
. That means my companions should go before their classes but I'd rather leave them as they are in the example.
Why does this order matter? Is there a workaround for this?
A possible workaround keeping the order you wished:
object A {
implicit val aFoo: FooTypeClass[A] = new FooTypeClass[A] {
def foo: A = new A {
override def toString = "a"
}
}
}
I keep on seeking for the explanation why object
(instead of val
) doesn't fit.
来源:https://stackoverflow.com/questions/20380800/scala-implicits-resolution-mechanism-is-declaration-order-dependent