在Scala的隐式实例中强制执行优先级

在Scala的隐式实例中强制执行优先级,scala,typeclass,implicit,Scala,Typeclass,Implicit,这是问题的后续行动 假设我有两个特征,Trait2扩展了Trait1。每个trait都有一个特定的typeclass实例Eq。我想让Trait2的typeclass实例的优先级高于Trait1的优先级。但是,下面的代码(低优先级隐式技巧)不起作用 trait Eq[-A] { def eq(a: A, b: A): Boolean } object Eq { implicit object IntEq extends Eq[Int] { def eq(a: Int, b: In

这是问题的后续行动

假设我有两个特征,
Trait2扩展了Trait1
。每个trait都有一个特定的typeclass实例
Eq
。我想让
Trait2
的typeclass实例的优先级高于
Trait1
的优先级。但是,下面的代码(低优先级隐式技巧)不起作用

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 Trait1[+A]
trait Trait2[+A] extends Trait1[A]

object Implicits extends LowPriorityImplicits {
  implicit def Eq2[T: Eq]: Eq[Trait2[T]] = ???
}

trait LowPriorityImplicits {
  implicit def Eq1[T: Eq]: Eq[Trait1[T]] = ???
}

object Test2 extends App {

  def f[T: Eq](x: T) = ???
  import Implicits._

  val t1 = new Trait1[Int] {}
  val t2 = new Trait2[Int] {}

  f(t2) // COMPILATION ERROR!

}
将引发以下编译错误:

Error:(33, 4) ambiguous implicit values:
 both method Eq1 in trait LowPriorityImplicits of type [T](implicit evidence$2: Eq[T])Eq[Trait1[T]]
 and method Eq2 in object Implicits of type [T](implicit evidence$1: Eq[T])Eq[Trait2[T]]
 match expected type Eq[Trait2[Int]]
  f(t2)
   ^

如何强制执行typeclass实例的优先级关系?

类型参数中的差异与Scala对类型类的编码不匹配。如果您想编译它,只需试试这个

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 Trait1[A]
trait Trait2[A] extends Trait1[A]

object Implicits extends LowPriorityImplicits {
  implicit def Eq2[T: Eq]: Eq[Trait2[T]] = ???
}

trait LowPriorityImplicits {
  implicit def Eq1[T: Eq]: Eq[Trait1[T]] = ???
}

object Test2 extends App {

  def f[T: Eq](x: T) = ???
  import Implicits._

  val t1 = new Trait1[Int] {}
  val t2 = new Trait2[Int] {}

  f(t2) // COMPILATION ERROR!

}
如果您确实希望
Eq[Trait2[A]]
的行为类似于
Eq[Trait1[A]]
的子类型,则可以使用隐式转换作为解决方法