gpt4 book ai didi

scala - 为什么会发生这种隐含的歧义行为?

转载 作者:行者123 更新时间:2023-12-01 11:12:44 25 4
gpt4 key购买 nike

我有一个类型类 Search ,它有一个实例 Search[A]如果我们有 TypeClass1[A]TypeClass2[A]实例。优先考虑1实例。

编译如下:

trait TypeClass1[A]
trait TypeClass2[A]
trait Search[A]

object Search extends LPSearch {
implicit def case1[A](implicit ev: TypeClass1[A]): Search[A] = null
}

trait LPSearch {
implicit def case2[A](implicit ev: TypeClass2[A]): Search[A] = null
}

object Test {
implicit val ev1: TypeClass1[Int] = null
implicit val ev2: TypeClass2[Int] = null
implicitly[Search[Int]]
}

正如我所料,隐式搜索找到 case1 , 找到 ev1 , 并停止搜索。

但是,如果我们更改 TypeClass2为了有更多的结构,隐式搜索停止工作:

trait TypeClass1[A]
trait TypeClass2[M[_], A]
trait Search[A]

object Search extends LPSearch {
// This is the same as before
implicit def case1[A](implicit ev: TypeClass1[A]): Search[A] = null
}

trait LPSearch {
implicit def case2[M[_], A](implicit ev: TypeClass2[M, A]): Search[M[A]] = null
}

object Test {
implicit val ev1: TypeClass1[List[Int]] = null
implicit val ev2: TypeClass2[List, Int] = null

// Does not compile:
implicitly[Search[List[Int]]]
}

为什么在上面的例子中最后一行没有编译?

它失败了 ambiguous implicit values , 都说 case1case2满足条件。

在 Scala 2.12.8 和 2.13.0 上观察到的行为

最佳答案

Scala 规范说:

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在从定义 case2 的类(特征)派生的对象中定义但反之亦然。
  • case2case1 一样具体但反之亦然。

  • 所以 case1的相对权重在 case2是 1+0=1 和 case2 的相对权重在 case1是 0+1=1。所以是歧义。
    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]]]
    在第二种情况下,使用低优先级特征是没有意义的,因为如果两个隐式都匹配预期类型, case2当它们被定义在同一个对象中时是首选。所以试试
    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
    }

    关于scala - 为什么会发生这种隐含的歧义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57933865/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com