Scala 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.
https://www.scala-lang.org/files/archive/spec/2.13/07-implicits.html#implicit-parameters
The relative weight of an alternative
A
over an alternativeB
is a number from 0 to 2, defined as the sum of
- 1 if
A
is as specific asB
, 0 otherwise, and- 1 if
A
is defined in a class or object which is derived from the class or object definingB
, 0 otherwise.
https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#overloading-resolution
-
case1
is defined in an object which is derived from the class (trait) definingcase2
but not vice versa. -
case2
is as specific ascase1
but not vice versa.
So relative weight of case1
over case2
is 1+0=1 and relative weight of case2
over case1
is 0+1=1. So it’s ambiguity.
Error: ambiguous implicit values:
both method case2 in trait LPSearch of type [M[_], A](implicit ev: App.TypeClass2[M,A])App.Search[M[A]]
and method case1 in object Search of type [A](implicit ev: App.TypeClass1[A])App.Search[A]
match expected type App.Search[List[Int]]
implicitly[Search[List[Int]]]
In the second case there is no sense to use low-priority trait since if both implicits match expected type, case2
is preferred when they are defined in the same object. So try
object Search {
implicit def case1[A](implicit ev: TypeClass1[A]): Search[A] = null
implicit def case2[M[_], A](implicit ev: TypeClass2[M, A]): Search[M[A]] = null
}