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

このコードをコンパイルすると、次のエラーが発生します。

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

コンパニオン オブジェクトの が のオブジェクトよりも優先implicit defされないのはなぜですか?SubtraitSupertrait

サブトレイトimplicit defのコンパニオン オブジェクトの s が、スーパートレイトのオブジェクトよりも優先されることを望みます。

アップデート

LowPriorityImplicitsトリックも機能しません。Scala の暗黙的なインスタンスでの優先順位の適用を参照してください。

4

1 に答える 1

1

あなたのコードは暗黙の非曖昧性ルールに違反しているようです。

Programming in Scalaから、第 1 版:

あいまいでない規則: 挿入できる変換が他にない場合にのみ、暗黙的な変換が挿入されます。コンパイラに x + y を修正するための 2 つのオプションがある場合、たとえば convert1(x) + y または convert2(x) + y のいずれかを使用すると、エラーが報告され、どちらかを選択することは拒否されます。他のものよりもいくつかの変換を優先する、ある種の「ベスト マッチ」ルールを定義することは可能です。ただし、そのような選択は、非常にあいまいなコードにつながります。コンパイラが convert2 を選択すると想像してください。しかし、あなたはこのファイルを初めて使用し、convert1 しか認識していません。別の変換が適用されたと考えるのに多くの時間を費やす可能性があります。

全文はこちらでご覧いただけます

于 2016-04-29T05:41:42.777 に答える