2011-07-16 17 views
14

El siguiente pseudo-Scala, se obtiene una "referencia cíclico ilegal" error:¿Por qué esta referencia cíclica con una proyección de tipo es ilegal?

trait GenT[A] 
trait T extends GenT[T#A] { 
    type A 
} 

Preguntas: ¿Por qué esto es ilegal? ¿Hay un problema fundamental con la solidez o es una limitación del sistema de tipo Scala? ¿Hay una solución alternativa?

Mi intención es crear un rasgo T con un miembro de tipo A que se puede elevar bajo demanda a un parámetro de tipo mediante el superretrato GenT[A]. Una aplicación podría ser la expresión de limitaciones, por ejemplo

def foo[A, S1 <: GenT[A], S2 <: GenT[A]] ... 

Esto podría ser utilizado como si fuera def foo[S1 <: T, S2 <:T] ... con la restricción de que S1#A == S2#A.

Si la técnica fuera posible, también podría ayudar a la pregunta: ¿How to specialize on a type projection in Scala?

Nota: Yo podría utilizar en lugar de GenTT en todas partes, pero estoy tratando de evitar que, debido a que podría causar una gran cantidad de parámetros de tipo para extenderme por todo mi código "infecciosamente".

Las dos preguntas siguientes parecen similares, pero son de un tipo diferente de referencia cíclico:

Respuesta

16

En su ejemplo inicial se puede romper el ciclo mediante la introducción de un auxiliar escriba entre GenT [A] y T,

trait GenT[A] 
trait TAux { type A } 
trait T extends TAux with GenT[TAux#A] 

Pero por su motivador ejemplo, no creo que deba seguir esta ruta. La restricción que está buscando puede expresarse directamente mediante un refinamiento,

trait T { type A } 
def foo[A0, S1 <: T { type A = A0 }, S2 <: T { type A = A0 }] ... 

También tener en cuenta que puede surgir un miembro de tipo como un parámetro de tipo a través de un tipo alias,

trait T { type A } 
type TParam[A0] = T { type A = A0 } 
def foo[A0, S1 <: TParam[A0], S2 <: TParam[A0]] ... 
+0

gran información, ¡Gracias! De hecho, estaba tratando de salir a la superficie del miembro tipo. –

Cuestiones relacionadas