2010-07-09 13 views
12

Qualcuno può spiegare perché il secondo esempio di seguito non verrà compilato?Perché il codice non è sufficientemente generico?

'Test 2' restituisce "errore FS0670: questo codice non è sufficientemente generico. La variabile di tipo^a non può essere generalizzata perché ne uscirebbe l'ambito.". Non riesco a capire questo messaggio di errore.

// Test 1 
type test1<'a> = | A of 'a 
    with 
    override t.ToString() = 
     match t with 
     | A a -> a.ToString() 

// Test 2 
type test2<'a> = | A of 'a 
    with 
    override t.ToString() = 
     match t with 
     | A a -> string a 

// Test 3 
type test3<'a> = | A of 'a 
    with 
    override t.ToString() = 
     match t with 
     | A a -> string (a :> obj) 

risposta

5

Ecco un altro Repro:

let inline f< ^T>(x:^T) = box x 

type test4<'a> = | A of 'a 
    with 
    member t.M() = 
     match t with 
     | A a -> f a 

string è una funzione inline che utilizza i vincoli di tipo statico, e la diagnostica di errore per tali funzioni sono a volte poveri. Non capisco veramente il messaggio diagnostico, ma il punto è, nel sito di chiamata, non conosciamo il tipo generico 'a, il che significa che non possiamo in linea la versione corretta della chiamata a string (o f in la mia repro). Ad es. il caso in cui si upcast a obj, sappiamo che vogliamo inline la versione obj di string, in modo che è ok.

0

immagino che sia perché stringa ha una firma (obj -> string) in modo da utilizzare stringa da solo impone una ad essere di tipo obj. (F # non fa cast impliciti.)

+1

'string' [è in effetti' 'T -> string'] (http://msdn.microsoft.com/en-gb/library/ee340491.aspx), quindi questo dovrebbe funzionare in teoria. Non ho una spiegazione migliore per l'errore però. –

+0

Oh sì, ho appena messo uno spago ;; in F # interattivo per ottenere il tipo. Presumibilmente l'uso della stringa sta forzando la compilazione a forzare un tipo sull'input e sta scegliendo obj come il minimo comune denominatore? – Massif

Problemi correlati