Если a.SS =:= a.out.SS
, тогда мы сможем использовать одно вместо другого. Это так?
Нет.
val x: a.SS = "hello"
val y: a.out.SS = "hello"
Компилируя это, я получаю:
ScalaFiddle.scala:29: error: type mismatch;
found : lang.this.String("hello")
required: Super2.this.SS
(which expands to) S
val y: a.out.SS = "hello"
Похоже, Scala понимает, что a.SS
действительно String
, что неудивительно.
Но ясно, что a.out.SS
не String
, а ... S
.
Как ни странно, это работает, хотя это явно неверно:
val b = A(1)
implicitly[a.out.SS =:= b.out.SS]
Если вы просто определите out
как тип this.type
, тогда ваш код будет работать.
Лучшее, что я могу придумать, это то, что при определении типа out
, Scala не может связать фактический тип, представленный S
, с out
, поэтому тип SS
при просмотре через out
просто имеет общий c тип S
.
Тип Out
, похоже, понимает фактический тип, представленный S
, поэтому это работает:
implicitly[a.SS =:= a.Out#SS]
implicitly[a.SS <:< a.Out#SS]
implicitly[a.Out#SS <:< a.SS]
, и это правильно не компилируется:
val b = A(1)
implicitly[a.Out#SS =:= b.Out#SS]