我希望在使 forgetBA
再次隐式化之后编译以下代码。
trait ImplicitExample {
trait AA[T]
trait AB[T] extends AA[T]
trait BA[T] extends AA[T]
trait BB[T] extends AB[T] with BA[T]
object AA {
implicit def forgetAB[T: AB]: AA[T] = implicitly[AA[T]]
/*implicit*/ def forgetBA[T: BA]: AA[T] = implicitly[AA[T]]
}
object AB {
implicit def forgetBB[T: BB]: AB[T] = implicitly[AB[T]]
}
object BA {
implicit def forgetBB[T: BB]: BA[T] = implicitly[BA[T]]
}
object BB {
implicit object BBInt extends BB[Int]
}
val AAInt = implicitly[AA[Int]]
}
我知道这会导致不明确的隐式解析问题,所以我正在寻找一种方法来表明对一个隐式解析的偏好。
我听说以某种方式插入中间特征可能会有所帮助,但我似乎找不到解释。
最佳答案
通常的技巧是这样写:
trait LowPriorityAAInstances {
implicit def forgetAB[T: AB]: AA[T] = implicitly[AA[T]]
}
object AA extends LowPriorityAAInstances {
implicit def forgetBA[T: BA]: AA[T] = implicitly[AA[T]]
}
这将在为 T
寻找 AA
实例时给予 forgetBA
优先级,其中有一个 BA
(即使周围有 AB
的实例,仍然在编译)。
命名完全是约定俗成的问题,但最好用它来表明您只是以这种方式分解 AA
的定义以适应隐式搜索机制。
关于scala - 在 Scala 中消除隐式解析的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22650832/