2011-01-06 12 views
5

El siguiente código Scala parece ser válida:Error en el sistema de tipos de Scala?

class A[X] 
class C[M[X] <: A[X]] 

class Main 

new C[A] 

que esperaba el compilador para realizar la inferencia de tipos del tipo A, pero después he intentado lo siguiente:

new C[A[Int]] 

me dieron el siguiente mensaje de error :

(fragment of Main.scala):11: error: this.A[Int] takes no type parameters, expected: one 
println(new C[A[Int]]) 

Respuesta

2

Usted no declaró X como un parámetro de tipo para C. Intente lo siguiente:

class C[X, M[X] <: A[X]] 
+0

esto tampoco hará el trabajo. El problema es que C espera un tipo con un parámetro de tipo. Cuando pruebe el nuevo C [A], esto funcionará, porque A toma un argumento de tipo. – tim

+0

Esto no funcionará: C ahora espera dos parámetros de tipo. – gpampara

6

Pruebe esta sintaxis.

class C[M <: A[_]] 

Esto significa que C es una clase que tiene un parámetro de tipo, que debe ser una subclase de A y toma un parámetro tipo.

15

Veamos qué significa esto en inglés sencillo.

class A[X] 

significa: dejar que A sea una clase que toma un parámetro de tipo.

class C[M[X] <: A[X]] 

significa: sea C una clase que toma un parámetro de tipo, que debe ser una clase que toma un parámetro de tipo Y, con parámetros, es una subclase de la clase A parametrizada con el mismo tipo.

Cuando se escribe

new C[A] 

que estás diciendo: crear una instancia de C con A como parámetro. ¿Cumple A con los criterios anteriores? Sí, es una clase que toma un parámetro de tipo, y parametrizada es una subclase de sí misma parametrizada.

Sin embargo, cuando se escribe

new C[A[Int]] 

el parámetro de tipo que está tratando de dar a C, A [Int], no se ajusta a los criterios: A [Int] no toma ningún parámetro de tipo, que el compilador te dice amablemente. (Y tampoco es una subclase de A [X])

+1

Esta es la respuesta correcta; lo único que añadiría (para ayudar en las búsquedas web) es que este es un ejemplo de tipo de mayor nivel, donde el parámetro tipo a C se conoce como tipo * -> *. A [Int] por el contrario simplemente tiene kind *. –

+0

¿Querías decir 'A' en lugar de' C'? 'A [Int]' tiene el tipo '*', pero A debe ser '* -> *', ¿no? Entonces 'C' debería ser' (* -> *) -> * '? – Emre

0

No desea que su clase tome UN parámetro de tipo, ¡no quiere que tome dos! Dos soluciones posibles:

class A[X] { 
    type T = X 
} 
class C[M <: A[_]] { 
    //use M#T if you want the type T was parameterized with. 
} 

O bien, puede hacer lo siguiente:

class A[X] 
class C[T, M[A] <: A[A]] { 
    //when you want the type, write M[T], not M. 
} 

Sin embargo, lo que probablemente quiere es la siguiente:

class A[X] 
class C[M <: A[_]] 
+0

Para hacerlo más fácil, este es el equivalente en java: clase A {...} // para todos. clase C > {...} // primero. no es perfecto, sin embargo. // segundo no es posible. – Anonymous

1

Está todo explicado here, se centran en el "Common Trampas "porque es bastante TLTR.

Cuestiones relacionadas