2012-05-31 7 views
5

Wie kann def someA (in trait B) trait A mit dem gleichen C#MyType wie in B? (Dann A#MyType =:= B#MyType)Kuchen Muster und Typen

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

} 

Es lässt sich nicht kompilieren: Typenkonflikt;

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

Antwort

3

Sie erklären können doSomething und myType den Pfad unabhängige Version von MyType zu verwenden, 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, es kompiliert, aber Sie können nicht einen bestimmten SomeType mit B mischen. – jwinandy

0

Ich bin mir ziemlich sicher, dass Sie das nicht tun können, da Pfad unabhängige Typen sind nur dass - wenn A <> B dann A # T ist streng anders als B # T (dh A # T wird nie sein = = = B # T).

Das heißt, es ist sicher zu werfen, so dass Sie immer etwas wie someA.doSomething(myType.asInstanceOf[someA#MyType]) tun können. Hässlich aber funktioniert.

+0

Es funktioniert nicht? Ich meine, Sie können keinen instabilen Bezeichner darstellen. – jwinandy