Se stai cercando un riferimento pulito e funzionale all'inferenza di tipo, sono un po 'parziale rispetto a " Inferenza del tipo nel contesto " di Gundry, McBride e McKinna del 2010 , anche se questo potrebbe non essere una buona guida per le attuali implementazioni esistenti .
Penso che parte della risposta sia che, al di là della limitazione del valore, non c'è davvero molta difficoltà ad adattare l'inferenza di tipo Hindley-Milner ai linguaggi imperativi: se si definisce e1; e2
come zucchero sintattico (fn _ => e2) e1
e si definisce while e1 do e2
come zucchero sintattico per whiledo e1 (fn () => e2)
, dove whiledo
c'è un regolare funzione ricorsiva
fun whiledo g f = if g then (f (); whiledo g f) else ();
allora tutto funzionerà bene, inclusa l' inferenza del tipo.
Per quanto riguarda la limitazione del valore essendo una tecnica speciale, mi piace la seguente storia; Sono abbastanza sicuro di averlo raccolto da Karl Crary. Considera il seguente codice, che la limitazione del valore ti impedirà di scrivere in ML:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
Confrontalo con il seguente codice, che è totalmente privo di problemi:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
Sappiamo cosa fa il secondo esempio: crea due nuove celle ref contenenti NONE
, quindi inserisce SOME 5
la prima (an int option ref
), quindi inserisce SOME "Hello"
la seconda (a string option ref
).
x
x
∀ α . ref ( opzione ( α ) )x
Λ α . ref [ α ] ( NONE )
Ciò suggerirebbe che un comportamento "buono" del primo esempio è comportarsi esattamente allo stesso modo del secondo esempio: creare un'istanza del lambda a livello di tipo due volte diverse. La prima volta x
con int
cui creiamo un'istanza , che causerà la x [int]
valutazione di una cella di riferimento NONE
e quindi SOME 5
. La seconda volta x
con string
cui creiamo un'istanza , il che farà caso x [string]
per valutare una cella di riferimento ( diversa! ) NONE
E quindi SOME "Hello"
. Questo comportamento è "corretto" (tipo sicuro), ma non è sicuramente quello che un programmatore si aspetterebbe, ed è per questo che abbiamo la limitazione del valore in ML, per evitare che i programmatori affrontino questo tipo di comportamento inaspettato.
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
. Quindi a livello di una domanda di ricerca, è la risposta che stai cercando "applica tecniche sviluppate in Caml / SML, inclusa la restrizione del valore"?