Là các loại bị xóa trong Haskell?


13

Haskell có một khái niệm về các chức năng chung của Cameron, có một số điểm tương đồng rõ ràng với lisp phổ biến không có kinh nghiệm với Haskell cũng như với lisp thông thường, tôi có thể rất gần đúng ở đây. Điều này có nghĩa là người ta có thể định nghĩa một to_stringcơ sở chung để xác định biểu diễn chuỗi cho tất cả các loại. Tất nhiên, cơ sở phải được xác định trong các trường hợp đặc biệt nhưng có một to_stringchức năng có chữ ký của nó α → string.

Các loại có bị xóa trong Haskell, như chúng ở OCaml không? Nếu có, việc triển khai các chức năng chung của Wikipedia như thế nào trong Haskell khác với chức năng chung, trong đó các loại là động và do đó không bị xóa?

Tôi hiểu rằng chi tiết triển khai là cụ thể của trình biên dịch, nhưng có lẽ có các quy định chung cho nhiều hoặc tất cả các triển khai.


5
Hãy nhớ rằng bạn có thể không thể định nghĩa một hàm không tầm thường a -> String. Bạn có nhiều khả năng sẽ có một ràng buộc kiểu, như Show a => a -> String.
DJG

Câu trả lời:


16

Câu trả lời cho đến nay là sai lệch.

Cần phải có sự phân biệt giữa đa hình "tham số" và "quá tải ad-hoc". Tham số có nghĩa là "hành xử thống nhất cho tất cả các loại a", trong khi "ad-hoc" - điều mà Simon gọi là đa hình - thay đổi việc thực hiện dựa trên loại.

Ví dụ về cả hai reverse :: [a] -> [a], đó là tham số, và show :: Show a => a -> String"ad-hoc" bị quá tải.

Nếu bạn muốn có thêm một trực giác trừu tượng, tôi nghĩ sẽ giúp xem xét các lớp động từ ngôn ngữ tự nhiên 'hoạt động' cho tất cả các đối tượng, như "sở hữu" hoặc "nghĩ về" không gây ra ràng buộc nào cho đối tượng, nhưng " để mở "đòi hỏi những gì chúng ta đang nói về có thể được mở. Tôi có thể 'nghĩ về một cánh cửa' và 'mở một cánh cửa', trong khi thật vô nghĩa khi ví dụ 'mở một cái cây'. Lấy ví dụ thậm chí xa hơn "để mở" là "ad-hoc đa hình" là "để mở một cửa sổ" và "để mở một vé khiếu nại với dịch vụ khách hàng" là hai điều rất khác nhau. Nếu điều này có vẻ gượng ép - hãy quên nó đi! Nó làm việc cho tôi.

Cả hai đều được giải quyết tại thời gian biên dịch, tuy nhiên, và trên thực tế "bị xóa". Modulo nhiều phần mở rộng GHC và Haskell Template vv loại được trên thực tế bị xóa tại thời gian biên dịch và không bao giờ kiểm tra trên thời gian chạy.

Các hàm đa hình tham số hoạt động giống hệt nhau cho tất cả các loại, do đó chỉ cần tạo một đoạn mã, trong khi trình biên dịch quyết định tại thời điểm biên dịch phiên bản nào của hàm "loại phân loại" cần được chạy tại một điểm chương trình cụ thể. Đây cũng là lý do tại sao hạn chế một thể hiện cho mỗi loại cho mỗi loại lớp và công việc "newtype" tương ứng tồn tại.

Việc thực hiện được trình bày chi tiết trong sách giáo khoa SPJ và giấy Wadler và Blotts về các loại lớp .


Bạn có nghĩ rằng tôi nên xóa câu trả lời của tôi?
Simon Bergot

Không, thật tốt với cảnh báo của bạn về việc không đạt được từ vựng chính xác :)
Kris

Bạn có thể mở rộng một chút về lý do tại sao GHC có thể xóa các loại không? Có phải nhờ gõ chính?
Simon Bergot

2
Nói chung trong thời gian chạy, các hàm đa hình tham số chỉ có thể tồn tại một lần và gọi các hàm đa hình ad-hoc thông qua một số phương thức gửi ảo hoặc tất cả mã có thể được tạo riêng cho từng loại và gọi liên kết tĩnh. Việc thực hiện là đúng theo quan điểm ngôn ngữ (lưu ý rằng Haskell không có các loại đa hình; điều đó chỉ có thể được tạo bằng foralltiện ích mở rộng GHC ).
Jan Hudec

Có phần mở rộng GHC nào không cho phép xóa các loại không? Quá tải là tĩnh và không có loại phụ thuộc hoàn toàn Tôi không thể nghĩ ra bất cứ điều gì
Daniel Gratzer

1

cảnh báo: nền tảng của tôi về CS không mạnh lắm, vì vậy tôi có thể không luôn luôn sử dụng từ vựng chính xác và tôi có thể sai ở một số điểm. Dù sao, đây là sự hiểu biết của tôi:

Tôi nghĩ rằng bạn đang nhầm lẫn thuốc generic với đa hình.

Các loại chung chung như List<Foo>được sử dụng để mô tả các loại lấy các loại khác làm tham số và cho phép kiểm tra loại phong phú hơn.

Một hàm chung trong haskell có thể là count:: List a -> Int. Nó chấp nhận danh sách của bất kỳ loại nào và trả về số lượng phần tử. Chỉ có một thực hiện.

Thông thường, khi xác định Danh sách, bạn không thể thừa nhận bất cứ điều gì về T. Bạn chỉ có thể lưu trữ và trả lại.

Của bạn to_stringChức năng là một chức năng đa hình, có nghĩa là nó sẽ hoạt động khác nhau trong các trường hợp khác nhau. Trong haskell, điều này được thực hiện với các kiểu chữ, hoạt động giống như tính từ cho các loại.

Bạn có một kiểu chữ Show, trong đó xác định một show :: a -> Stringchức năng.

Khi một kiểu Foothực hiện kiểu chữ Show, nó phải cung cấp định nghĩa về show. Loại này sau đó có thể được sử dụng trong các chức năng yêu cầu Showvòng loại (như trong Show a => a -> whatever). Haskell không thể xóa các loại, vì các hàm đó phải tìm ra cách thực hiện đúng của showhàm.


Trong lisp thông thường, các hàm đa hình được gọi là các hàm chung chung của II II II và tôi đã sử dụng cùng một từ vựng (khó hiểu). Câu trả lời của bạn rất hữu ích và lập luận cuối cùng của bạn khá thuyết phục. .-)
dùng40989

Chỉ có một cách thực hiện, chỉ có một cách thực hiện có ý nghĩa, chắc chắn, nhưng có vô số khả năng. Hàm số loại a → b có | b | ^ | a | triển khai có thể (xem xét số lượng chức năng của loại Bool → Bool) và danh sách không có giới hạn kích thước trên.
Jon Purdy
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.