2012-12-07 7 views
17

In genere, F # non consente alle variabili di pattern di verificarsi due volte nello stesso pattern. Ma nel codice seguente, F # non si lamenta - si tratta di un bug?Perché una variabile può essere associata due volte in un modello?

type foo = { A: int } 
let test (x, {A = x}) = x 
let result = test ("bla", {A = 3}) 
+2

Esempio più semplice - 'let test (x, (x, y)) = 1' –

+3

Non sono sicuro del motivo per cui questa domanda ha avuto un downvote - mi sembra un problema interessante! Penso che questo sia un bug e puoi segnalarlo inviando email a _fsbugs_ a _microsoft_ dot _com_. –

+0

Non sono sicuro se si tratta di un bug - è probabilmente seguendo le seguenti regole di scoping vincolando alla x definita più vicina. – plinth

risposta

5

non credo che questo sia un errore, anche se sembra confusa, ma è solo il modo in cui il compilatore compila il valore sopra vincolante.

Sezione 14.6.3 afferma che se la definizione del valore non è un singolo modello di valore (come è il caso qui), l'espressione elaborato è

tmp <typars1… typarsn> = expr 
ident1 <typars1> = expr1 
… 
identn <typarsn> = exprn 

dove tmp è un identificatore fresco e ogni risultato expri da la compilazione del pattern pat (§7) contro input tmp [da spec].

vedere ciò che il compilatore fa, potremmo usare un # citazione F, ad esempio:

<@ let test (x:int, {A = x:int})= x in test (3, {A = 5}) @>;; 

In formato stringa vengo (lasciando un po 'di roba):

Let (test, 
    Lambda (tupledArg, 
      Let (x, TupleGet (tupledArg, 0), 
        Let (_arg1, TupleGet (tupledArg, 1), 
         Let (x, PropertyGet (Some (_arg1), A, []), x)))), 
    Application (test, NewTuple (Value (3), NewRecord (foo, Value (5))))) 

che è per questo che prendi la "inner" x.

Non penso che sia un bug ma forse sarebbe più coerente se questo generasse un avvertimento.

+0

È perché i nomi dei valori di ombreggiatura sono consentiti in F #? – Goswin

Problemi correlati