Seguendo un esempio minimo di osservazione (che tipo di mi stupito):destrutturazione parziale in corrispondenza del pattern (F #)
type Vector = V of float*float
// complete unfolding of type is OK
let projX (V (a,_)) = a
// also works
let projX' x =
match x with
| V (a, _) -> a
// BUT:
// partial unfolding is not Ok
let projX'' (V x) = fst x
// consequently also doesn't work
let projX''' x =
match x with
| V y -> fst y
Qual è la ragione che rende impossibile la corrispondenza con un tipo parzialmente eliminata?
Alcuni decostruzioni parziali sembrano essere ok:
// Works
let f (x,y) = fst y
EDIT: Ok, ora capisco il motivo "tecnico" del comportamento descritto (Grazie per le vostre risposte & commenti). Tuttavia, penso che questo linguaggio sia un po '"innaturale" rispetto al resto della lingua:
"Algebricamente", a me sembra strano distinguere un tipo "t" dal tipo "(t)". Le parentesi (in questo contesto) sono usate per dare la precedenza come per es. in "(t * s) * r" vs "t * (s * r)". risponde anche FSI di conseguenza, se io mando
type Vector = (int * int)
o
type Vector = int * int
alla FSI, la risposta è sempre
tipo di vettore = int * int
Dato quelli osservazioni, si conclude che "int * int" e "(int * int)" denotano esattamente gli stessi tipi e t che tutte le occorrenze di uno potrebbero essere sostituite con qualsiasi altro codice (rif. trasparenza) ... che come abbiamo visto non è vero.
Inoltre sembra significativo che, per spiegare il comportamento in questione, abbiamo dovuto ricorrere a "come appare un codice dopo la compilazione" piuttosto che alle proprietà semantiche del linguaggio che indica che ce ne sono alcune " tensioni "tra semantica del linguaggio e ciò che il compilatore effettivamente fa.
Provalo con 'type Vector = V of (float * float)' per fare in modo che il compilatore usi una tupla effettiva per il contenuto. – kvb
funziona! ... ma come potrebbe fare la differenza ... Voglio dire type Vector = (V of float) * float non sarebbe nemmeno valido? –
La domanda è: "V di x * y" significa "V contiene una tupla di elementi di tipi xey" o "V contiene due campi distinti di tipo xey"? Se non si parentesi la tupla, il compilatore assume quest'ultimo, ma se lo si fa parentesi, significa il primo. Questa distinzione è importante soprattutto per l'interoperabilità con altri linguaggi .NET, ma come hai scoperto può anche influire sul modo in cui interagisci con valori di tale tipo all'interno di F # in alcune circostanze. – kvb