Why is this implicit ambiguity behaviour happening?

后端 未结 1 1652
有刺的猬
有刺的猬 2020-12-07 03:30

I have a typeclass Search, which has an instance Search[A] if we have a TypeClass1[A] or a TypeClass2[A] instance. With p

相关标签:
1条回答
  • 2020-12-07 04:13

    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 alternative B is a number from 0 to 2, defined as the sum of

    • 1 if A is as specific as B, 0 otherwise, and
    • 1 if A is defined in a class or object which is derived from the class or object defining B, 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) defining case2 but not vice versa.

    • case2 is as specific as case1 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
    }
    
    0 讨论(0)
提交回复
热议问题