随播对象中的Scala隐式类型类优先级 [英] Scala implicit typeclass precedence in companion objects

查看:106
本文介绍了随播对象中的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 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] {})

编译此代码时,会发生以下错误:

When compiling this code, the following error occurs:

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] {})
   ^

为什么Subtrait随播对象中的implicit def的优先级比Supertrait中的优先级高?

Why doesn't the implicit def in the Subtrait companion object has higher precedence than the one in Supertrait?

我希望子特性的伴随对象中的implicit def的优先级高于父特性中的implicit def的优先级.

I'd like that implicit defs in the companion object of subtraits have higher precedence than those in supertraits.

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

The LowPriorityImplicits trick does not work either. See Enforcing precedence in implicit instances in Scala.

推荐答案

您的代码似乎违反了非歧义规则的隐式要求.

It looks like your code violates the Non-Ambiguity Rule for implicits.

来自 Scala编程,第一版:

非歧义规则:仅当存在隐式转换时,才会插入 没有其他可能的转换要插入.如果编译器有两个 修复x + y的选项,例如使用convert1(x)+ y或convert2(x) + y,则它将报告错误并拒绝在它们之间进行选择.可以定义某种最佳匹配"规则 偏好某些转化而不是其他转化.但是,这样的选择导致 真正晦涩的代码.假设编译器选择convert2,但是您 是文件的新手,只知道convert1-您可以花一个 很多时间认为应用了另一种转换!

Non-Ambiguity Rule: An implicit conversion is only inserted if there is no other possible conversion to insert. If the compiler has two options to fix x + y, say using either convert1(x) + y or convert2(x) + y, then it will report an error and refuse to choose between them. It would be possible to define some kind of "best match" rule that prefers some conversions over others. However, such choices lead to really obscure code. Imagine the compiler chooses convert2, but you are new to the file and are only aware of convert1—you could spend a lot of time thinking a different conversion had been applied!

可以在此处找到完整的文本..

The complete text can be found here.

这篇关于随播对象中的Scala隐式类型类优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆