Trong this talk around the 1:20 mark, Edward Kmett đề cập đến việc thiếu "loại lớp backtracking" trong Haskell. Hãy xem xét các vấn đề của "thiết lập sự bình đẳng" (nơi trật tự và đa dạng được bỏ qua) thực hiện trên danh sách:Có cách giải quyết nào cho việc thiếu loại backtracking không?
equals :: [a] -> [a] -> Bool
Bởi bản chất của các lớp học loại I không thể cung cấp một sự so sánh hiệu quả O (n ²) nếu tất cả chúng ta phải là Eq a
nhưng so sánh hiệu quả các danh sách trong O (n log n) nếu chúng ta có Ord a
.
Tôi đã hiểu lý do tại sao cơ sở như vậy sẽ có vấn đề. Đồng thời, Edward nói rằng có những "thủ thuật bạn có thể chơi" đề cập đến các gia đình kiểu mẫu.
Do đó câu hỏi của tôi là, những gì sẽ là một cách giải quyết để đạt được hiệu quả tương tự:
- một (không hiệu quả) thực hiện mặc định được cung cấp
- nếu người dùng có thể cung cấp thêm một số thông tin về loại, chúng tôi "mở khóa" triển khai hiệu quả hơn
Cách giải quyết này không nhất thiết phải sử dụng các loại lớp.
Chỉnh sửa: Một số người đề xuất chỉ cần cung cấp equals
và efficientEquals
làm hai phương pháp riêng biệt. Nói chung tôi đồng ý rằng đây là cách tiếp cận thành ngữ-Haskell hơn. Tuy nhiên, tôi không tin rằng điều này là luôn luôn có thể. Ví dụ, nếu bằng phương pháp trên là bản thân một phần của một lớp học loại:
class SetLike s where
equals :: Eq a => s a -> s a -> Bool
Giả sử rằng lớp này đã được cung cấp bởi người khác vì vậy tôi không thể chỉ cần thêm một chức năng mới cho typeclass. Bây giờ tôi muốn xác định cá thể cho []
. Tôi biết rằng []
luôn có thể cung cấp triển khai equals
bất kể ràng buộc nào có trên a
nhưng tôi không thể cho biết trường hợp của mình để sử dụng phiên bản hiệu quả hơn nếu có thêm thông tin về a
.
Có lẽ tôi có thể bọc danh sách trong một loại mới và gắn thẻ nó với một số thông tin loại bổ sung?
Điều này khá thú vị và tôi không biết câu trả lời cho điều này. Nhưng một giải pháp nhanh chóng và bẩn sẽ là xác định một hàm khác như 'effectiveEquals :: (Ord a) => [a] -> [a] -> Bool' và' equals :: (Eq a) => [a] -> [a] -> Bool'. – Shoe
Hãy làm rõ rằng chúng ta đang nói về việc so sánh các danh sách _đánh giá thứ tự_ (và có thể là bội số). Rõ ràng '(==)' không yêu cầu O (n^2) trên danh sách. – chi
IIRC, GHC cho phép một chỉ định '{- # RULE ... equals = effectiveOrdEquals # -}' chỉ được áp dụng nếu kiểm tra kiểu RHS. Bằng cách này, các cuộc gọi được biết đến tĩnh liên quan đến các loại đặt hàng sẽ nhận được phiên bản hiệu quả. – chi