2012-08-26 13 views
5

¿Cómo me muevo con la equivalencia de dos tipos dependientes de ruta que sé que son iguales pero el compilador no?Scala: Equivalencia de tipos dependientes de ruta

Uso de Scala 2.10.0 M7 Estoy tratando de convertir un AST de un universo a otro.

case class MacroBridge(context: Context) { 
    def toMacroTree(tree: treehugger.forest.Tree): context.universe.Tree = ??? 
    def fromMacroTree(tree: context.universe.Tree): treehugger.forest.Tree = ??? 
} 

Dentro de una aplicación macro, puedo utilizarlo como:

val bridge = treehugger.MacroBridge(c) 
def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree) 

Sin embargo, esto da lugar a un error de compilación:

[error] /scalamacros-getting-started/library/Macros.scala:21: type mismatch; 
[error] found : c.universe.Tree 
[error] required: bridge.context.universe.Tree 
[error] possible cause: missing arguments for method or constructor 
[error]  def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree) 

En el código c anterior es claramente la misma valor como bridge.context, pero tal vez porque es un comprobador de tipo de valor no puede verificarlo. Poner tipo de restricción generalizada no ayudó:

def fromMacroTree[A](tree: A)(implicit ev: A =:= context.universe.Tree): Tree = 

En la macro de esto todavía dio lugar a un error:

[error] /scalamacros-getting-started/library/Macros.scala:21: Cannot prove that c.universe.Tree =:= bridge.context.universe.Tree. 
[error]  def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree) 

necesito el acceso a context.universe para que pueda llegar a otros tipos dependientes como TermName. ¿Hay un mejor trabajo alrededor además de fundición ?:

def fromMacroTree(tree: c.universe.Tree): Tree = 
    bridge.fromMacroTree(tree.asInstanceOf[bridge.context.universe.Tree]) 
+0

tal vez algo como 'def fromMacroTree [T <: Tree] (tree: T): T = ???' y 'fromMacroTree [tree.type] (tree)' helps? – sschaef

+0

Supongo que ambos 'Tree's tienen algún tipo súper común, ¿lo intentaron? – pedrofurla

+0

@sschaef Recibí el error: 'tipo argumentos [c.universe.Tree] no se ajusta al método de los límites de parámetros de tipo deMacroTree [T <: bridge.context.universe.Tree]' –

Respuesta

9

pude hacer lo siguiente para trabajar:

case class MacroBridge[C <: Context](context: C) { 
    def fromMacroTree(tree: context.universe.Tree): context.universe.Tree = ??? 
} 

trait MB { 
    def meth(c: Context) { 
    val bridge = MacroBridge[c.type](c) 
    def fromMacroTree(tree: c.universe.Tree): c.universe.Tree = 
     bridge.fromMacroTree(tree) 
    } 
} 

que tenía casi la same problem hace algún tiempo.

+0

'val bridge = treehugger.MacroBridge [c .type] (c) 'fue la respuesta. ¡Gracias! –

Cuestiones relacionadas