Vì vậy, có rất nhiều ưu điểm khi có typeclasses ở dạng C a Bool
. Chủ yếu là vì chúng cho phép bạn thực hiện bất kỳ thao tác lôgic nào giữa hai ràng buộc khi thông thường C a
chỉ ngầm ẩn tất cả mọi thứ.Chuyển đổi một ràng buộc lớp tùy ý `C a` thành` C a Bool`
Nếu chúng ta xem xét ~
một hạn chế lớp, điều này có thể được thực hiện như vậy
class Equal x y b | x y -> b
instance Equal x x True
instance False ~ b => Equal x y b
Nhưng những gì làm cho trường hợp này đặc biệt là một thực tế rằng việc đưa x x
vào đầu của các ví dụ tương đương với x ~ y =>
và sau đó x y
trong đầu. Đây không phải là trường hợp cho bất kỳ typeclass khác. Vì vậy, nếu chúng ta cố gắng làm điều gì đó tương tự cho một lớp C
chúng tôi nhận một cái gì đó giống như
class C' x b | x -> b
instance C x => C' x True
instance False ~ Bool => C' x b
Thật không may điều này không làm việc kể từ khi chỉ là một trong những trường hợp đó bao giờ sẽ được chọn vì họ không phân biệt đối xử vào loại x
vì vậy bất kỳ loại nào khớp với cả hai đầu.
Tôi cũng đọc https://www.haskell.org/haskellwiki/GHC/AdvancedOverlap lại không áp dụng cho bất kỳ lớp học nào C
vì yêu cầu bạn viết lại tất cả các phiên bản của lớp gốc. Lý tưởng nhất, tôi muốn mã của tôi để làm việc với GHC.Exts.Constraint
và KindSignatures
để C
có thể tham số.
Vì vậy, đối với một lớp học như thế này
class Match (c :: * -> Constraint) x b | c x -> b
Làm thế nào để viết các trường hợp để Match c x True
khi và chỉ khi c x
, Match c x False
khác?
Lệnh 'C một hình thức Bool' mạnh hơn' C a'.Về cơ bản, bạn hỏi làm thế nào để thu thập tập hợp các thể hiện của một loại lớp, điều đó là không thể. – user2407038
@ user2407038 Không phải là tôi nghi ngờ bạn nhưng tôi đã nghe 'không thể' liên quan đến hệ thống kiểu trước và nó hóa ra là sai. –
Tôi không biết liệu tôi có thể đưa ra một lý lẽ thuyết phục hay không, nhưng tôi sẽ cố gắng. Giả sử bạn đã viết 'Match'. Trong mô-đun A, tôi định nghĩa 'dữ liệu X = X', và' lớp A b x | b -> x; a :: Proxy b -> x; instance A True Int; instance A False Bool', 'test :: forall x b y. (So khớp Eq x b, A b y) => x -> y; test _ = a (Proxy :: Proxy b) '. Tôi có mô-đun B (nhập A), trong đó kiểu 'test X' phải là' Int'. Trong mô-đun C (nhập A), tôi có 'instance Eq X' để' test X :: Bool'. Mô đun D nhập khẩu B và C. Mô-đun D không thể bắt buộc B và C biên dịch lại, do đó, 'kiểm tra X' phải nghịch lý hai loại cùng một lúc. – user2407038