Подтвердить что ты не робот

Scala неявное преобразование из родительского признака

Следующий код не компилируется:

import scala.language.implicitConversions

trait Base {
  class Wrp[+T](val v: T) // wrapper / internal representation
}

trait BooleanOps extends Base {
  // implicit conversion
  implicit def lift2BooleanOpsCls(x: Boolean): BooleanOpsCls =
    new BooleanOpsCls(new Wrp[Boolean](x))
  class BooleanOpsCls(wx: Wrp[Boolean]) {
    def ||(wy: =>Wrp[Boolean]): Wrp[Boolean] = new Wrp[Boolean](wx.v || wy.v)
  }
}

trait MyExample extends BooleanOps {
  // test method
  def foo(): Wrp[Boolean] = {
    val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
    ret
  }
}

Вывод:

MyExample.scala:18: error: type mismatch;
 found   : MyExample.this.Wrp[Boolean]
 required: Boolean
        val ret: Wrp[Boolean] = false || new Wrp[Boolean](true)
                                         ^

Но если I:

1) поместите class Wrp вне базы

или

2) переместите тело BooleanOps в MyExample

все компилируется.

Почему исходный пример не работает? Если у вас есть некоторое понимание этого поведения, помощь будет оценена по достоинству. Спасибо.

4b9b3361

Ответ 1

Одна из проблем - это вызов по имени аргумента в def ||(wy: =>Wrp[Boolean])
если вы переписываете его на def ||(wy: Wrp[Boolean]), он работает

но я согласен с тем, что это странно, что он работает, если вы перемещаете Wrp или BooleanOpsCls! Предполагаемый или ошибка неявного разрешения

Ответ 2

Исходный пример будет работать, если вы переименуете метод ||. Компилятор находит метод false.||() и не пытается искать неявный, который также может работать там.

Ответ 3

Проблема заключается в том, что не существует одного класса с именем Wrp (игнорируйте T на мгновение) - Base не определяет Wrp, а скорее определяет именованный подкласс каждого конкретного класса, продолжается Base. Имплициты - тоже красная селедка. Ошибка в том, что раздача является упоминанием MyExample.this.Wrp - помните, что такого класса нет, даже если MyExample - val x = new MyExample будет иметь тип Object with MyExample.