So, implicit precedence is based on two factors: one is about the scope of declaration itself having precedence (scope A extending scope/trait B, or scope A being a companion object of a type extended from a type with scope B as its companion object). The other simply mentions that declaration A is more specific than declaration B. Now, when reading it for the first time I had several possible interpretations in mind, especially considering potential parameters (implicit and not) of implicit method and type parameters. Experience seemed to teach me that it means that the type of the returned value by declaration A, after all type inference/tapply, is a subtype of the return type of declaration B. So, this is fine:
class A
class B extends A
implicit val A = new A
implicit val B = new B
implicitly[A]
Why this doesn't compile, then?
implicit class A(val toInt :Int) {
def ! = (1 /: (2 to toInt))(_ * _)
}
implicit class B(i :Int) extends A(i)
1.!
When this does?
class A(val toInt :Int) {
def ! = (1 /: (2 to toInt))(_ * _)
}
class B(i :Int) extends A(i)
implicit val A = { i :Int => new A(i) }
implicit val B = { i :Int => new B(i) }
1.!
Is it another case of 'the compiler works in mysterious ways'?