Si vous recherchez une référence fonctionnelle et soignée à l'inférence de type, je suis un peu partial à Gundry, McBride et McKinna 2010 " Type Inference in Context ", bien que cela ne soit pas un bon guide pour les implémentations existantes réelles .
Je pense qu'une partie de la réponse est que, au-delà de la restriction de valeur, il n'y a vraiment pas beaucoup de difficulté à adapter l'inférence de type Hindley-Milner aux langues impératives: si vous définissez e1; e2comme sucre syntaxique pour (fn _ => e2) e1et définissez while e1 do e2comme sucre syntaxique pour whiledo e1 (fn () => e2), où whiledoest un régulier fonction récursive
fun whiledo g f = if g then (f (); whiledo g f) else ();
alors tout fonctionnera bien, y compris l' inférence de type.
Quant à la restriction de valeur étant une technique spéciale, j'aime l'histoire suivante; Je suis presque sûr de l'avoir récupéré auprès de Karl Crary. Considérez le code suivant, dont la restriction de valeur vous empêchera d'écrire en ML:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
Comparez-le au code suivant, ce qui ne pose aucun problème:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
Nous savons ce que fait le deuxième exemple: il crée deux nouvelles cellules ref contenant NONE, puis met SOME 5dans le premier (an int option ref), puis met SOME "Hello"dans le second (a string option ref).
Mais réfléchissez au premier exemple en termes de représentation xdans le système F (le lambda-calcul polymorphe). Dans un tel paramètre, xserait une valeur de type " ", ce qui signifie que, comme terme, la valeur de doit être un (type) lambda: "∀α.ref(option(α))xΛα.ref[α](NONE) ".
Cela suggérerait qu'un «bon» comportement du premier exemple consiste à se comporter exactement de la même manière que le deuxième exemple - instancier le lambda de niveau type à deux moments différents. La première fois que nous instancions xavec int, ce qui entraînera x [int]d'évaluer une tenue de cellule de référence NONEpuis SOME 5. La deuxième fois, nous instancions xavec string, ce qui sera le cas x [string]pour évaluer une cellule de référence ( différente! ) NONEEt ensuite SOME "Hello". Ce comportement est "correct" (type-safe), mais ce n'est certainement pas ce à quoi un programmeur s'attendrait, et c'est pourquoi nous avons la restriction de valeur en ML, pour éviter aux programmeurs de gérer ce type de comportement inattendu.
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end. Donc, au niveau d'une question de recherche, la réponse que vous recherchez est-elle «d'appliquer des techniques développées en Caml / SML, y compris la restriction de valeur»?