Скала неявный конфликт преобразования странно - PullRequest
0 голосов
/ 21 декабря 2018

Я обнаружил странную ошибку компиляции:

class A
class B

object M {
  implicit val mA: M[A] = d => new A
  implicit val mB: M[B] = d => new B
}

trait M[K] {
  def get(d: D): K
}

object D {
  implicit def f[K](d: D)(implicit m: M[K]): K = m.get(d)
}

class D

object Main {
  val d = new D
  val a: A = d // This line can't compile!
}

, которая не может быть скомпилирована из-за конфликта mA и mB.Но это странно, поскольку тип B не соответствует нашему типу результата.

Если я прокомментирую mB следующим образом

class A
class B

object M {
  implicit val mA: M[A] = d => new A
  //implicit val mB: M[B] = d => new B
}

trait M[K] {
  def get(d: D): K
}

object D {
  implicit def f[K](d: D)(implicit m: M[K]): K = m.get(d)
}

class D

object Main {
  val d = new D
  val a: A = d // can compile
}

, который может компилироваться.Почему нельзя скомпилировать первый случай?

1 Ответ

0 голосов
/ 21 декабря 2018

Это происходит потому, что когда компилятор пытается найти неявную переменную для передачи от m до f, он не знает ожидаемый тип возвращаемого значения (поскольку это зависит от того, какая неявная переменная будет выбрана).Это создает некую циклическую зависимость.

PS: Вам не нужно указывать f неявно, чтобы проиллюстрировать эту проблему.

...