[EDIT: Voilà một vài từ trên mỗi]
Có một số cách để mở rộng suy luận kiểu HM. Câu trả lời của tôi dựa trên nhiều, ít nhiều thành công, cố gắng thực hiện một số trong số họ. Cái đầu tiên tôi vấp phải là đa hình tham số . Loại hệ thống đang cố gắng mở rộng HM theo hướng này có xu hướng về Hệ thống F và do đó yêu cầu chú thích loại. Hai phần mở rộng đáng chú ý theo hướng này tôi đã đi qua là:
HMF, nó cho phép suy luận kiểu cho tất cả các loại System-F, có nghĩa là bạn có thể có định lượng phổ quát "ở giữa" của một loại, sự xuất hiện của chúng không hoàn toàn nằm ở phạm vi cao nhất như đối với các loại đa hình của HM. Bài viết nêu rõ rằng không có quy tắc rõ ràng nào tồn tại về số lượng và nơi cần chú thích loại. Ngoài ra các loại là của Hệ thống F, các thuật ngữ thường không có loại chính.
MLF không chỉ là một phần mở rộng của HM, nó còn là một phần mở rộng của Hệ thống F lấy lại thuộc tính loại chính của HM bằng cách đưa ra một loại định lượng giới hạn trên các loại. Một so sánh đã được thực hiện bởi các tác giả, MLF mạnh hơn hẳn so với HMF và chú thích chỉ được yêu cầu cho các tham số được sử dụng đa hình.
Một cách khác để mở rộng HM là thông qua biến thể của miền ràng buộc.
HM (X) là Hindley-Milner được tham số hóa trên miền ràng buộc X. Trong phương pháp này, thuật toán HM tạo ra các ràng buộc được gửi đến một bộ giải miền cho X. Đối với HM thông thường, bộ giải miền là thủ tục hợp nhất và miền bao gồm của tập hợp các thuật ngữ xây dựng từ các loại và các biến loại.
Một ví dụ khác cho X có thể là các ràng buộc được thể hiện bằng ngôn ngữ của số học Presburger (trong đó trường hợp suy luận / kiểm tra loại có thể quyết định được) hoặc bằng ngôn ngữ của số học Peano (không còn có thể quyết định được). X thay đổi theo một phổ các lý thuyết, mỗi lý thuyết có các yêu cầu riêng liên quan đến số lượng và nội địa hóa của các chú thích loại cần thiết và từ không hoàn toàn đối với tất cả chúng.
Các lớp loại của Haskell cũng là một loại mở rộng của miền ràng buộc bằng cách thêm các biến vị ngữ loại của biểu mẫu MyClass(MyType)
(có nghĩa là tồn tại một thể hiện của MyClass cho loại MyType).
Các lớp loại bảo tồn suy luận kiểu vì về cơ bản chúng là một khái niệm trực giao (gần như) chúng thực hiện đa hình adhoc .
Ví dụ, lấy một ký hiệu val
loại val :: MyClass a => a
mà bạn có thể có các thể hiện MyClass A
, MyClass B
v.v. Khi bạn tham chiếu đến ký hiệu đó trong mã của mình, thực ra là do suy luận kiểu đã được thực hiện mà trình biên dịch có thể suy ra thể hiện của lớp nào sẽ sử dụng. Điều này có nghĩa là loại val
phụ thuộc vào bối cảnh mà nó được sử dụng. Đó cũng là lý do tại sao chạy một val
câu lệnh dẫn đến mộtambiguous type error
: trình biên dịch không thể suy ra bất kỳ loại nào dựa trên ngữ cảnh.
Đối với các hệ thống loại nâng cao hơn như GADT, họ kiểu, Kiểu phụ thuộc, Hệ thống (F), v.v., loại không còn là "loại" nữa, chúng trở thành các đối tượng tính toán phức tạp. Ví dụ, điều đó có nghĩa là hai loại không giống nhau không nhất thiết phải khác nhau. Vì vậy, loại bình đẳng trở nên không tầm thường (tất cả).
Để cho bạn một ví dụ về độ phức tạp thực tế, hãy xem xét loại danh sách phụ thuộc: NList a n
đâu a
là loại đối tượng trong danh sách và n
độ dài của nó.
Hàm chắp thêm sẽ có loại append :: NList a n -> NList a m -> NList a (n + m)
và hàm zip sẽ là zip :: NList a n -> NList b n -> NList (a, b) n
.
Hãy tưởng tượng bây giờ chúng ta có lambda \a: NList t n, b: NList t m -> zip (append a b) (append b a)
. Ở đây, đối số đầu tiên của zip là loại NList t (n + m)
và thứ hai của loại NList t (m + n)
.
Hầu như giống nhau, nhưng trừ khi trình kiểm tra loại biết rằng "+" bắt đầu trên các số tự nhiên, nó phải từ chối hàm vì (n + m) không theo nghĩa đen (m + n). Nó không còn là về kiểm tra suy luận / loại kiểm tra, đó là về việc chứng minh định lý.
Các loại chất lỏng dường như đang làm một số loại suy luận phụ thuộc. Nhưng theo tôi hiểu, nó không thực sự là loại phụ thuộc, giống như các loại HM thông thường mà suy luận bổ sung được thực hiện để tính các giới hạn tĩnh.
Tôi hi vọng cái này giúp được.