Al lavoro mi è stato assegnato il compito di dedurre alcune informazioni sul tipo di un linguaggio dinamico. Riscrivo sequenze di affermazioni in let
espressioni nidificate , in questo modo:
return x; Z => x
var x; Z => let x = undefined in Z
x = y; Z => let x = y in Z
if x then T else F; Z => if x then { T; Z } else { F; Z }
Dal momento che sto partendo da informazioni di tipo generali e provando a dedurne tipi più specifici, la scelta naturale è quella dei tipi di perfezionamento. Ad esempio, l'operatore condizionale restituisce un'unione dei tipi dei suoi rami vero e falso. In casi semplici, funziona molto bene.
Mi sono imbattuto in un intoppo, tuttavia, quando ho cercato di inferire il tipo di quanto segue:
function g(f) {
var x;
x = f(3);
return f(x);
}
Che viene riscritto in:
\f.
let x = undefined in
let x = f 3 in
f x
HM e di conseguenza . Il tipo effettivo che voglio poter inferire è:g : ( I n t → I n t ) → I n t
Sto già usando dipendenze funzionali per risolvere il tipo di +
operatore sovraccarico , quindi ho pensato che fosse una scelta naturale usarle per risolvere il tipo di f
dentro g
. Cioè, i tipi di f
in tutte le sue applicazioni insieme determinano in modo univoco il tipo di g
. Tuttavia, a quanto pare, i fundep non si prestano molto bene a numeri variabili di tipi di fonte.
Comunque, l'interazione tra polimorfismo e tipizzazione di raffinamento è problematica. Quindi c'è un approccio migliore che mi manca? Attualmente sto digerendo "Tipi di perfezionamento per ML" e apprezzerei più letteratura o altri suggerimenti.