Узор и виды тортов
Как может def someA
(в trait B
) использовать trait A
с тем же C#MyType
как в B
? (Затем A#MyType =:= B#MyType
)
trait C {
type MyType
}
trait A {
self: C =>
def doSomething(s: MyType) { println(s.toString)}
}
trait B {
self: C =>
def someA: A
def myType: MyType
def action = someA.doSomething(myType)
}
// Mix part
case class Ahoy(value: String)
trait ConcreteC extends C {
type MyType = Ahoy
}
class PieceOfCake extends B with ConcreteC {
val someA = new A with ConcreteC
val myType = Ahoy("MyType")
}
Не компилируется: несоответствие типов;
[error] found : B.this.MyType
[error] required: _1.MyType where val _1: A
[error] def action = someA.doSomething(myType))
2 ответа
Решение
Вы можете объявить doSomething
а также myType
использовать независимую от пути версию MyType
, SomeType#MyType
:
trait SomeType {
type MyType
}
trait A {
self: SomeType =>
def doSomething(s: SomeType#MyType) { println(s.toString)}
}
trait B {
self: SomeType =>
def someA: A
def myType: SomeType#MyType
def action = someA.doSomething(myType)
}
Я почти уверен, что вы не можете сделать это, так как независимые от пути типы - это просто - если A<>B, то A#T строго отличается от B#T (то есть A#T никогда не будет =:= B# Т).
Тем не менее, это безопасно, так что вы всегда можете сделать что-то вроде someA.doSomething(myType.asInstanceOf[someA#MyType])
, Некрасиво но работает.