这是问题的后续伴生对象中的 Scala 隐式类型类优先级 https://stackoverflow.com/questions/36928125/scala-implicit-typeclass-precedence-in-companion-objects.
假设我有两个特征,Trait2 extends Trait1
。每个特征都有一个特定的类型类实例Eq
。我想让类型类实例的优先级Trait2
高于Trait1
。然而,下面的代码(LowPriorityImplicits
技巧)不起作用。
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)
^
如何强制执行类型类实例的优先关系?
类型参数的变化与 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]]
,您也许可以使用隐式转换作为解决方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)