Nếu bạn đang tìm kiếm một tài liệu tham khảo gọn gàng, đầy đủ chức năng cho suy luận kiểu, thì tôi là một phần của " Kiểu suy luận trong ngữ cảnh " của Gundry, McBride và 2010 của McKinna , mặc dù điều này có thể không phải là một hướng dẫn tốt cho bất kỳ triển khai thực tế hiện có nào .
Tôi nghĩ một phần của câu trả lời là, ngoài giới hạn giá trị, thực sự không có quá nhiều khó khăn để thích ứng kiểu suy luận của Hindley-Milner với các ngôn ngữ bắt buộc: nếu bạn định nghĩa e1; e2
là đường cú pháp (fn _ => e2) e1
và định nghĩa while e1 do e2
là đường cú pháp whiledo e1 (fn () => e2)
, thì đâu whiledo
là thông thường Hàm đệ quy
fun whiledo g f = if g then (f (); whiledo g f) else ();
sau đó mọi thứ sẽ hoạt động tốt, bao gồm cả suy luận kiểu.
Đối với việc hạn chế giá trị là một kỹ thuật đặc biệt, tôi thích câu chuyện sau đây; Tôi khá chắc chắn rằng tôi đã nhặt nó từ Karl Crary. Xem xét mã sau đây, hạn chế giá trị sẽ ngăn bạn viết bằng ML:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
So sánh nó với mã sau đây, điều này hoàn toàn không có gì khó hiểu:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
Chúng ta biết ví dụ thứ hai làm gì: nó tạo ra hai ô ref mới chứa NONE
, sau đó đặt SOME 5
vào ô thứ nhất (an int option ref
), sau đó đặt SOME "Hello"
vào ô thứ hai (a string option ref
).
x
x
∀ α . ref ( tùy chọn ( α ) )x
Λ α . ref [ α ] ( KHÔNG )
Điều này sẽ gợi ý rằng một hành vi "tốt" của ví dụ đầu tiên là hành xử chính xác giống như cách mà ví dụ thứ hai hành xử - khởi tạo lambda cấp độ hai lần khác nhau. Lần đầu tiên chúng ta khởi tạo x
với int
, điều này sẽ gây ra x [int]
việc đánh giá một ô tham chiếu NONE
và sau đó SOME 5
. Lần thứ hai chúng tôi khởi tạo x
với string
, trường hợp này sẽ x [string]
đánh giá một ô tham chiếu ( khác! ) NONE
Và sau đó SOME "Hello"
. Hành vi này là "chính xác" (loại an toàn), nhưng chắc chắn đó không phải là điều mà lập trình viên mong đợi và đây là lý do tại sao chúng tôi có giới hạn giá trị trong ML, để tránh các lập trình viên xử lý loại hành vi bất ngờ này.
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
:). Vì vậy, ở cấp độ của một câu hỏi nghiên cứu, câu trả lời bạn đang tìm kiếm "áp dụng các kỹ thuật được phát triển trong Caml / SML, bao gồm cả hạn chế giá trị"?