Có thể suy luận Hindley-Milner cho ngôn ngữ Go?


22

Tôi đã đọc rằng Hindley-Milner không hoạt động với các hệ thống loại có các lớp con và có các tính năng hệ thống loại khác cũng không hoạt động tốt với nó. Go hiện chỉ có loại suy luận rất hạn chế trong :=toán tử. Nhưng Go không có các lớp con theo nghĩa truyền thống, chỉ có các giao diện trông rất giống các lớp loại của Haskell hoạt động tốt với suy luận của Hindley-Milner.

Vì vậy, nguyên tắc suy luận của Hindley-Milner có thể hoạt động theo nguyên tắc đối với Go theo cách tương tự như đối với Haskell không? Hay Go có các tính năng khác phá vỡ nó? (Mặt khác, Haskell cũng có một số tính năng không hoạt động với Hindly-Milner, nếu bạn sử dụng những tính năng đó bạn phải nhập thủ công các phần đó trong chương trình của mình.)

Câu trả lời:


35

Suy luận kiểu Hindley-Milner được sử dụng cho các hệ thống loại Hindley-Milner, một hạn chế của hệ thống loại System-F. Đặc điểm thú vị của các hệ thống loại HM là chúng có tính đa hình tham số (hay còn gọi là thuốc generic). Đó là tính năng hệ thống loại lớn nhất mà Golang từ chối có.

Với sự hạn chế bực bội đó, suy luận kiểu kiểu HM là không thể. Chúng ta hãy xem mã chưa được kiểm tra:

func f(a) {
  return a.method()
}

Các loại là fgì? Chúng tôi có thể nhận thấy rằng aphải có một phương thức, vì vậy chúng tôi có thể sử dụng giao diện ẩn danh : func f(a interface { method() ??? }) ???. Tuy nhiên, chúng tôi không có ý tưởng gì về kiểu trả về. Với các biến kiểu, chúng ta có thể khai báo kiểu như

func f[T](a interface{ method() T }) T

Tuy nhiên, Go không có biến loại nên điều này sẽ không hoạt động. Mặc dù các giao diện ngầm làm cho một số khía cạnh của suy luận kiểu dễ dàng hơn, bây giờ chúng ta không có cách nào để tìm ra kiểu trả về của một lệnh gọi hàm. Hệ thống HM yêu cầu tất cả các hàm phải được khai báo thay vì được ngụ ý và mỗi tên chỉ có thể có một loại duy nhất (trong khi các phương thức của Go có thể có các loại khác nhau trong các giao diện khác nhau).

Thay vào đó, Go yêu cầu các hàm luôn được khai báo đầy đủ, nhưng cho phép các biến sử dụng suy luận kiểu. Điều này là có thể bởi vì phía bên phải của một bài tập variable := expressionđã có một loại đã biết tại thời điểm đó của chương trình. Kiểu suy luận kiểu này là đơn giản, chính xác và tuyến tính.

  • Loại của một biến được biết ngay lập tức tại điểm khai báo, trong khi suy luận của HM phải kiểm tra loại toàn bộ chương trình trước. Điều này cũng có tác động đáng kể đến chất lượng của các thông báo lỗi.
  • Cách tiếp cận suy luận kiểu Go sẽ luôn chọn loại cụ thể nhất cho một biến, ngược lại với HM chọn loại chung nhất. Điều này hoạt động rõ ràng với phân nhóm, ngay cả với các giao diện ngầm của Go.

24
@bishop Đó là "lý do" cho các giá trị cực kỳ nhỏ của "lý do".
hobbs

18
@bishop Đã thực hiện công việc biên dịch bằng các ngôn ngữ chung chung, tôi chắc chắn có thể đồng ý: thật khó để thực hiện mà không làm phức tạp đáng kể việc thực hiện. Tôi đã đi xa đến mức thậm chí thay thế "khó khăn" bằng "không thể." Tuy nhiên, đó không phải là vấn đề; Vấn đề là, nó có đáng để biến chứng thêm không? Và câu trả lời, cho bất cứ ai làm việc cùng và không có thuốc generic, rõ ràng là "có, chắc chắn!" Tôi phải hoàn toàn đồng ý với tuyên bố rằng việc từ chối thực hiện thuốc generic vì "ồ không, sự phức tạp" là ngu ngốc.
Mason Wheeler

18
Đây cũng là lý do tại sao các nhà phát triển Go giả vờ rằng tất cả các loại là xấu; Go có chức năng hạng nhất với đóng cửa từ vựng, và với điều đó khả năng tạo ra các chức năng bậc cao, nhưng nó không thể đưa chúng vào bất kỳ sử dụng tốt vì các loại chức năng cơ bản như map, filterreducetất cả đều không thể diễn tả trong Go rất hạn chế loại hệ thống.
hobbs

9
@hobbs And Go có thể là một ngôn ngữ thực sự tốt nếu được sửa, nhưng thay vào đó mọi người phải viết các thư viện thế hệ chung như gengengonerics
con mèo

14
@cat Thật là xấu hổ. Thoạt đầu, Go có vẻ như là một ngôn ngữ tuyệt vời chứa đầy những ý tưởng tuyệt vời, nhưng sau đó bạn nhận ra nó không có tính kế thừa và đa hình, vì vậy bạn không thể làm tốt OOP, và nó không có khái quát, vì vậy bạn không thể làm tốt về FP, còn bạn Tôi đang nhìn chằm chằm vô hồn vào màn hình hỏi "vậy chính xác thì bạn phải sử dụng ngôn ngữ này như thế nào?!?"
Mason Wheeler
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.