2011-05-06 13 views
8

asumir el rasgo siguiente:¿Es posible usar evidencia implícita para forzar la compatibilidad de tipo estático entre tipos abstractos?

trait A { 
    type B 
    def +(a:A):A 
} 

utilizo un tipo abstracto porque no quiero arrastrar alrededor de la B en el tipo de firma cada vez que necesito una A. ¿Es todavía posible añadir ninguna evidencia implícita (utilizando =: =, <: <, etc.) con el método + para que el compilador pueda exigir la aceptación de: A con B idénticas.

Mi primer instinto es decir que no, pero Scala me ha sorprendido gratamente antes. Cualquier ayuda sería apreciada.

Respuesta

10

No hay necesidad de pruebas implícita ... se puede usar un refinamiento explícita,

trait A { 
    self => 
    type Self = A { type B = self.B } 
    type B 
    def +(a : Self) : Self 
} 

(nótese el uso de una anotación de tipo auto para proporcionar un alias para el exterior 'esto' permitiendo que la define y la definición B's para ser distinguido en la definición de tipo Self).

transcripción REPL,

scala> trait A { self => type Self = A { type B = self.B } ; type B ; def +(a : Self) : Self } 
defined trait A 

scala> val ai = new A { type B = Int ; def +(a : Self) : Self = this } 
ai: java.lang.Object with A{type B = Int} = [email protected] 

scala> val ad = new A { type B = Double ; def +(a : Self) : Self = this } 
ad: java.lang.Object with A{type B = Double} = [email protected] 

scala> ai + ai 
res0: ai.Self = [email protected] 

scala> ad + ad 
res1: ad.Self = [email protected] 

scala> ai + ad 
<console>:9: error: type mismatch; 
found : ab.type (with underlying type java.lang.Object with A{type B = Double}) 
required: ai.Self 
     ai + ab 
+1

No puedo creer que el compilador no se queja de un ciclo! –

+1

¿El refinamiento estructural también depende de las reflexiones en el tiempo de ejecución? – user44242

+1

La reflexión en tiempo de ejecución solo se aplica cuando un refinamiento proporciona una nueva definición no de tipo que no está presente en su supertipo nominal (ver SLS 3.2.7). Eso no está sucediendo aquí, así que no, no hay reflexión en tiempo de ejecución involucrada. Puede verificar eso usando javap. –

Cuestiones relacionadas