2012-05-31 15 views
5

¿Cómo puede def someA (en trait B) usar trait A con el mismo C#MyType que en B? (Entonces A#MyType =:= B#MyType)Cake pattern and types

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

} 

No compila: tipo de falta de coincidencia;

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

Respuesta

3

Se puede declarar doSomething y myType utilizar la versión independiente de la ruta 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, compila, pero no se puede mezclar un SomeType más específico con B. – jwinandy

0

Estoy bastante seguro de que no se puede hacer eso, ya que los tipos de trayectoria independiente son sólo eso - si A <> B entonces A # T es estrictamente diferente de B # T (es decir, A # T será nunca be =: = B # T).

Dicho esto, es seguro lanzar, por lo que siempre puede hacer algo como someA.doSomething(myType.asInstanceOf[someA#MyType]). Feo pero funciona

+0

¿No funciona? Quiero decir que no puedes usar un identificador inestable. – jwinandy