2
trait Eq[-A] {
  def eq(a: A, b: A): Boolean
}
object Eq {
  implicit object IntEq extends Eq[Int] {
    def eq(a: Int, b: Int) = a == b
  }
}

trait Supertrait[+A]
object Supertrait {
  implicit def Eq[A: Eq]: Eq[Supertrait[A]] = ???
}

trait Subtrait[+A] extends Supertrait[A]
object Subtrait {
  implicit def Eq[A: Eq]: Eq[Subtrait[A]] = ???
}

def f[A](x: Subtrait[A])(implicit ev: Eq[Subtrait[A]]) = ???

f(new Subtrait[Int] {})

编译此代码时,出现以下错误:

Error:(32, 4) ambiguous implicit values:
 both method Eq in object Supertrait of type [A](implicit evidence$1: Eq[A])Eq[Supertrait[A]]
 and method Eq in object Subtrait of type [A](implicit evidence$2: Eq[A])Eq[Subtrait[A]]
match expected type Eq[Subtrait[Int]]
  f(new Subtrait[Int] {})
   ^

为什么implicit definSubtrait伴生对象的优先级不高于 in Supertrait

我希望implicit defsubtraits 的伴生对象中的 s 比 supertraits 中的优先级更高。

更新

这个LowPriorityImplicits技巧也不起作用。请参阅在 Scala 中的隐式实例中强制执行优先级

4

1 回答 1

1

看起来您的代码违反了隐含的非歧义规则

来自Programming in Scala,第 1 版:

非歧义规则:只有在没有其他可能的转换可以插入时才插入隐式转换。如果编译器有两个选项来修复 x + y,比如使用 convert1(x) + y 或 convert2(x) + y,那么它将报告错误并拒绝在它们之间进行选择。可以定义某种“最佳匹配”规则,该规则更喜欢某些转换而不是其他转换。但是,这样的选择会导致代码非常晦涩。想象一下编译器选择了convert2,但您是文件新手,只知道convert1——您可能会花很多时间认为已经应用了不同的转换!

完整的文本可以在这里找到。

于 2016-04-29T05:41:42.777 回答