Scala type constraint precedence in implicit resolution

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Scala type constraint precedence in implicit resolution



I have these 2 implicits


trait A[T]
val name: String


trait B

object A
implicit def product[T <: Product] = new A[T]
override val name: String = "product"


implicit def childOfB[T <: Product with B] = new A[T]
override val name: String = "child of B"




and if I try to find an implicit instance of A[C] where C is


A[C]


C


case class C() extends B



childOfB will be selected.


childOfB



I know it is logical but why does this happen? I cannot find it documented anywhere.




3 Answers
3



Scala Language Specification says:



If there are several eligible arguments which match the implicit
parameter's type, a most specific one will be chosen using the rules
of static overloading resolution.



Overloading resolution has a notion of one symbol being more specific than other. Precise, general definition of specificity is quite complex (as you can see in the specification linked above) but in your case it boils down to the fact that childOfB covers strictly a subset of types covered by product and therefore is more specific.


childOfB


product





can you also point me the lines related to this "subset" logic. The specification is too complex for my english.
– Minh Thai
Aug 12 at 8:19



Specification says



If there are several eligible arguments which match the implicit
parameter's type, a most specific one will be chosen using the rules
of static overloading resolution.



To extend @ghik's answer, from Programmming in Scala,



To be more precise, one implicit conversion is more specific than another if one of the following applies:



My guess is that "argument" in that quote refers also to type parameters, as is sugggested by


object A
implicit def A2Z[T <: A] = new Z[T] println("A")
implicit def B2Z[T <: B] = new Z[T] println("B")


trait A
trait B extends A

trait Z[T]

def aMethod[T <: A](implicit o: Z[T]) = ()

implicit val a: A = new A

aMethod // prints B even though we started with an A






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard