Jika Anda mencari referensi fungsional yang rapi untuk inferensi-tipe, saya sedikit mendukung Gundry, McBride, dan McKinna 2010 " Type Inference in Context ", meskipun ini mungkin bukan panduan yang baik untuk implementasi aktual apa pun yang ada .
Saya pikir bagian dari jawabannya adalah bahwa, di luar batasan nilai, sebenarnya tidak ada banyak kesulitan mengadaptasi inferensi tipe Hindley-Milner ke bahasa imperatif: jika Anda mendefinisikan e1; e2
sebagai gula sintaksis (fn _ => e2) e1
dan didefinisikan while e1 do e2
sebagai gula sintaksis untuk whiledo e1 (fn () => e2)
, di mana whiledo
biasa fungsi rekursif
fun whiledo g f = if g then (f (); whiledo g f) else ();
maka semuanya akan berfungsi dengan baik, termasuk inferensi tipe.
Adapun pembatasan nilai menjadi teknik khusus, saya suka cerita berikut; Saya cukup yakin saya mengambilnya dari Karl Crary. Pertimbangkan kode berikut, di mana batasan nilai akan mencegah Anda menulis dalam ML:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
Bandingkan dengan kode berikut, yang sama sekali tidak bermasalah:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
Kita tahu apa yang dilakukan contoh kedua: ia membuat dua sel ref baru yang mengandung NONE
, kemudian menempatkan SOME 5
yang pertama (an int option ref
), kemudian menempatkan SOME "Hello"
yang kedua (a string option ref
).
x
x
∀α.ref(option(α))x
Λα.ref[α](NONE)
Ini menunjukkan bahwa satu perilaku "baik" dari contoh pertama adalah berperilaku dengan cara yang persis sama dengan contoh kedua berperilaku - instantiate tipe-level lambda dua kali berbeda. Pertama kalinya kami instantiate x
dengan int
, yang akan menyebabkan x [int]
mengevaluasi ke sel tahanan referensi NONE
dan kemudian SOME 5
. Kedua kalinya kami instantiate x
dengan string
, yang akan kasus x [string]
untuk mengevaluasi ke ( berbeda! Holding) sel referensi NONE
dan kemudian SOME "Hello"
. Perilaku ini "benar" (tipe-aman), tetapi jelas bukan yang diharapkan oleh seorang programmer, dan inilah mengapa kami memiliki batasan nilai dalam ML, untuk menghindari programmer berurusan dengan jenis perilaku yang tidak terduga ini.
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
. Jadi pada tingkat pertanyaan penelitian, apakah jawaban yang Anda cari "terapkan teknik yang dikembangkan di Caml / SML, termasuk pembatasan nilai"?