2011-01-06 19 views
5

Il seguente codice Scala sembra valido:Bug nel sistema di tipi di Scala?

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

class Main 

new C[A] 

mi aspettavo che il compilatore per eseguire l'inferenza di tipo di tipo A, ma dopo che ho provato quanto segue:

new C[A[Int]] 

ho ottenuto il seguente messaggio di errore :

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

risposta

2

non hai dichiara X come parametro tipo per C. Prova quanto segue:

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

questo non farà il lavoro neanche. Il problema è che C si aspetta un tipo con un parametro di tipo. Quando provi la nuova C [A], questo funzionerà, perché A accetta un argomento di tipo. – tim

+0

Questo non funzionerà - C ora si aspetta due parametri di tipo. – gpampara

6

Prova questa sintassi.

class C[M <: A[_]] 

Ciò significa che C è una classe che prende un parametro tipo, che dovrebbe essere una sottoclasse di A e prende un parametro tipo.

15

Vediamo cosa significa in chiaro inglese.

class A[X] 

significa: sia A una classe che accetta un parametro di tipo.

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

significa: sia C una classe che accetta un parametro tipo, che dovrebbe essere una classe che accetta un parametro di tipo AND, parametrizzato, è una sottoclasse di classe A parametrizzati con lo stesso tipo.

Quando si scrive

new C[A] 

stai dicendo: creare un'istanza di C con A come parametro. A è conforme ai criteri sopra riportati? Sì, è una classe che accetta un parametro di tipo e la sua parametrizzazione è una sottoclasse di se stesso parametrizzata.

Tuttavia, quando si scrive

new C[A[Int]] 

il parametro di tipo si sta cercando di dare C, A [Int], non conformi ai criteri: A [Int] non accetta parametri di tipo, che il compilatore gentilmente ti dice (E nemmeno una sottoclasse di A [X].)

+1

Questa è la risposta corretta; l'unica cosa che aggiungerei (per facilitare le ricerche sul web) è che questo è un esempio di tipo più elevato, in cui il parametro di tipo a C si riferisce al tipo * -> *. Al contrario, [Int] ha semplicemente un carattere *. –

+0

Intendevi "A" invece di "C"? 'A [Int]' ha il tipo '*', ma A dovrebbe essere '* -> *', no? Quindi 'C' dovrebbe essere' (* -> *) -> * '? – Emre

0

Non vuoi che la tua classe prenda UN parametro di tipo, non vuoi prenderne due! Due possibili soluzioni:

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

In alternativa, si può fare:

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

Tuttavia, ciò che probabilmente si desidera è questo:

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

Per semplificare, questo è l'equivalente in java: classe A {...} // per tutti. classe C > {...} // primo. comunque non perfetto // secondo non è possibile. – Anonymous

1

E 'tutto spiegato here, si concentrano sul "Common Sezione "Insidie" perché è piuttosto TLTR.

Problemi correlati