Wenn Sie nach einer ordentlichen, funktionalen Referenz zur Typinferenz suchen, bin ich ein bisschen parteiisch gegenüber Gundry, McBride und McKinnas 2010 "Typinferenz im Kontext ", obwohl dies möglicherweise kein guter Leitfaden für tatsächlich vorhandene Implementierungen ist .
Ich denke, ein Teil der Antwort ist, dass es jenseits der Wertebeschränkung wirklich nicht so schwierig ist, die Inferenz des Hindley-Milner-Typs an imperative Sprachen anzupassen: Wenn Sie e1; e2
als syntaktischen Zucker für (fn _ => e2) e1
und while e1 do e2
als syntaktischen Zucker für definieren whiledo e1 (fn () => e2)
, wo whiledo
ist ein regulärer rekursive Funktion
fun whiledo g f = if g then (f (); whiledo g f) else ();
dann wird alles gut funktionieren, einschließlich Typinferenz.
Was die Wertebeschränkung betrifft, die eine spezielle Technik ist, mag ich die folgende Geschichte; Ich bin mir ziemlich sicher, dass ich es von Karl Crary abgeholt habe. Betrachten Sie den folgenden Code, den Sie aufgrund der Werteinschränkung nicht in ML schreiben können:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
Vergleichen Sie es mit dem folgenden Code, der völlig unproblematisch ist:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
Wir wissen , was das zweite Beispiel macht: es schafft zwei neue ref Zellen enthält NONE
, dann setzt SOME 5
in der ersten (ein int option ref
), dann setzt SOME "Hello"
in der zweiten (a string option ref
).
x
x
∀α.ref(option(α))x
Λα.ref[α](NONE)
Dies würde darauf hinweisen, dass ein "gutes" Verhalten des ersten Beispiels darin besteht, sich genauso zu verhalten wie das zweite Beispiel - das Lambda auf Typebene zwei verschiedene Male instanziieren. Das erste Mal instanziieren wir x
mit int
, was dazu führt, dass x [int]
eine Referenzzelle gehalten wird NONE
und dann SOME 5
. Das zweite Mal instanziieren wir x
mit string
, was x [string]
zu einem ( anderen! ) Referenzzellen-Holding führen wird NONE
und dann SOME "Hello"
. Dieses Verhalten ist "korrekt" (typsicher), aber es ist definitiv nicht das, was ein Programmierer erwarten würde, und deshalb haben wir die Wertbeschränkung in ML, um zu vermeiden, dass Programmierer mit dieser unerwarteten Art von Verhalten umgehen.
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
. Ist die Antwort, die Sie auf der Ebene einer Forschungsfrage suchen, "Anwenden von in Caml / SML entwickelten Techniken, einschließlich der Werteinschränkung"?