问题描述
在选择最具体的类型类中是否有任何方法可以使用多个合适的替代方法,而不会产生不同的隐式扩展?它看起来像这样
Is there any way of having multiple suitable alternatives in a type-class where the most specific is chosen, not producing diverging implicit expansion? It would look like this
trait A
trait B extends A
case class C extends B
trait Tester[-T] {def test (t : T) : Boolean}
object Tester{
def test[T] (t : T)(implicit tester : Tester[T]) = tester.test(t)
implicit def ATester = new Tester[A] {
override def test (a : A) = true
}
implicit def BTester = new Tester[B] {
override def test (b : B) = false
}
}
val c = C()
Tester.test(c)
我希望这产生假,因为C在继承层次结构中更接近B而不是A.
I want this to produce false as C is closer to B than to A in the inheritance hierarchy.
推荐答案
我将提供一些解释为什么这样做的方式 - 另一个答案有一个可能的解决方法。
I'll provide some explanation about why this works the way this does - the other answer has a possible workaround.
<$> c $ c> Tester [A] 被选中 Tester [B]
与类型 T $有关c $ c> in
Tester [-T]
be逆变。这意味着 Tester [A]
是 Tester [B]
的子类,
必须是 B
的超类 - 就像您的代码示例所示。
The reason that Tester[A]
gets picked over Tester[B]
has to do with type T
in Tester[-T]
being contravariant. This means that for Tester[A]
to be a subclass of Tester[B]
, A
must be a superclass of B
- just like your code sample shows.
因此,当方法 test
(带隐式参数)需要 Tester [C]
的子类型时,替代方案将是 Tester [B]
( Tester [C]
的子类)和 Tester [A]
(也是 Tester [C]
的子类,但更具体一个)。这就是为什么,根据选择最具体类型的规则,选择 Tester [A]
。
So when the method test
(with the implicit parameter) requires a subtype of Tester[C]
, the alternatives will be Tester[B]
(subclass of Tester[C]
) and Tester[A]
(also subclass of Tester[C]
, but a more specific one). This is why, according to the rule of choosing the most specific type, Tester[A]
gets chosen.
如果有一个类D扩展C
,并且一个隐式函数返回 Tester [D]
,如果不是参数 Tester [C]
的分辨率的一部分。
If there was a class D extends C
, and an implicit function that returns Tester[D]
, if would not be a part of the resolution for parameter Tester[C]
.
还有关于它的其他信息。
There's additional information about it here.
这篇关于多个备选方案之间的隐式搜索决策的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!