2012-05-31 39 views
5

Come può def someA (in trait B) utilizzare trait A con lo stesso C#MyType come in B? (Poi A#MyType =:= B#MyType)Tipi di torta e tipi

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") 

} 

non si compila: tipo non corrispondente;

[error] found : B.this.MyType 
[error] required: _1.MyType where val _1: A 
[error] def action = someA.doSomething(myType)) 

risposta

3

È possibile dichiarare doSomething e myType di utilizzare la versione cammino indipendente da 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) 
} 
+0

Ok, si compila, ma non è possibile mescolare un SomeType più specifico con B. – jwinandy

0

Sono abbastanza sicuro che non si può fare, dal momento che tipi di percorso indipendente sono solo che - se A <> B allora A # T è strettamente diverso da B # T (cioè A # T sarà mai be =: = B # T).

Detto questo, è sicuro eseguire il cast, quindi puoi sempre fare qualcosa come someA.doSomething(myType.asInstanceOf[someA#MyType]). Brutto ma funziona.

+0

Non funziona? Voglio dire che non puoi lanciare su un identificatore instabile. – jwinandy