Схема и виды торта

Как def someAtrait 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))

person jwinandy    schedule 31.05.2012    source источник


Ответы (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)
}
person Matthew Farwell    schedule 31.05.2012
comment
Хорошо, он компилируется, но вы не можете смешивать более специфичный SomeType с B. - person jwinandy; 31.05.2012

Я почти уверен, что вы не можете этого сделать, поскольку независимые от пути типы — это именно то, что: если A‹>B, то A#T строго отличается от B#T (т. е. A#T никогда быть =:= B#T).

При этом кастовать безопасно, поэтому вы всегда можете сделать что-то вроде someA.doSomething(myType.asInstanceOf[someA#MyType]). Некрасиво, но работает.

person Tomer Gabel    schedule 31.05.2012
comment
Это не работает? Я имею в виду, что вы не можете использовать нестабильный идентификатор. - person jwinandy; 31.05.2012