Tôi sẽ có cách tiếp cận tương tự nhưng hơi khác với câu trả lời của J. Abrahamson.
chính xác những gì bạn yêu cầu không thể được thực hiện, bởi vì các lớp học kiểu cần phải được giải quyết tĩnh, nhưng sự tồn tại của Show (a b)
có thể động tùy thuộc vào instantation của b
. Sự khởi tạo này được ẩn bên trong giá trị X
và do đó không hiển thị với trình kiểm tra loại khi bạn không có gì ngoài một nguồn gốc không xác định là X b
.
Nó sẽ được tốt đẹp để viết một điều kiện trên a
như Show (a b)
tồn tại bất cứ khi nào Show b
không, bởi vì khi đó sự tồn tại của Show (a b)
không phải là thực sự phụ thuộc vào b
như chúng ta đã biết rằng Show b
luôn luôn là sự thật.
Chúng tôi không thể viết điều kiện trực tiếp, nhưng chúng ta có thể thể hiện một cái gì đó giống như nó sử dụng GADTs:
{-# LANGUAGE GADTs #-}
data ShowDict a where
ShowDict :: Show a => ShowDict a
Loại ShowDict a
cung cấp một loại reification của lớp Show a
- đó là một cái gì đó chúng ta có thể vượt qua xung quanh và định nghĩa các hàm.
Đặc biệt chúng tôi bây giờ có thể định nghĩa một lớp Show1
thể hiện điều kiện Show (a b)
bất cứ khi nào chúng tôi có một Show b
:
class Show1 a where
show1Dict :: ShowDict b -> ShowDict (a b)
Và bây giờ chúng ta có thể xác định Show (X a)
về Show1
, bằng cách xây dựng ShowDict (a b)
và sau đó mô hình khớp trên đó để tiết lộ cá thể Show
:
{-# LANGUAGE ScopedTypeVariables #-}
instance Show1 a => Show (X a) where
show (X (v :: a b)) =
case show1Dict ShowDict :: ShowDict (a b) of
ShowDict -> "X (" ++ show v ++ ")"
Thực hiện đầy đủ hơn cũng sẽ có lude các thành viên khác của Show
(showsPrec
và showList
).
Những điều tốt đẹp về giải pháp này là chúng ta có thể dễ dàng xác định Show1
cho []
, tự động tái sử dụng cơ bản Show
dụ:
instance Show1 [] where
show1Dict ShowDict = ShowDict
Tôi cũng muốn tránh sự rất chung chung Show (a b)
dụ từ câu trả lời J. Abrahamson của, nhưng nhược điểm của việc đặt logic trong ví dụ Show
cho X
là chúng ta sẽ phải thực hiện nó theo cách thủ công thay vì nhận được hành vi tự động dẫn xuất cho hàm tạo.
Quá tệ. Mọi thứ mà sổ tay GHC nói về OverlappingInstances đều đáng sợ. – Will
Vâng, nó không được khuyến khích tuyệt vời. Show1 cũng có thể clobber các trường hợp khác khá dễ dàng. –