Tôi sẽ bắt đầu bằng cách giới thiệu một vấn đề cụ thể (StackOverflow guys như thế). Giả sử bạn định nghĩa một kiểu đơn giảnTại sao các trường hợp chỉ phù hợp với đầu của họ?
data T a = T a
kiểu Đây là một Functor
, Applicative
và Monad
. Bỏ qua việc tạo tự động, để có được những trường hợp đó, bạn phải viết từng trường hợp, mặc dù Monad
ngụ ý Applicative
, ngụ ý Functor
. Hơn thế nữa, tôi có thể xác định một lớp học như thế này
class Wrapper f where
wrap :: a -> f a
unwrap :: f a -> a
Đây là một tình trạng khá mạnh và nó chắc chắn ám chỉ Monad
, nhưng tôi không thể viết
instance Wrapper f => Monad f where
return = wrap
fa >>= f = f $ unwrap fa
vì này, vì một lý do , có nghĩa là "tất cả mọi thứ là một Monad
(mỗi f
), chỉ khi đó là một Wrapper
", thay vì "tất cả mọi thứ đó là một Wrapper
là một Monad
".
Tương tự, bạn không thể xác định các trường hợp Monad a => Applicative a
và Applicative a => Functor a
.
Một thứ khác mà bạn không thể làm (chỉ có thể liên quan, tôi thực sự không biết) là có một lớp là một siêu lớp của một lớp khác và cung cấp triển khai mặc định của lớp con. Chắc chắn, nó tuyệt vời mà class Applicative a => Monad a
, nhưng nó ít hơn nhiều tuyệt vời mà tôi vẫn phải xác định các trường hợp Applicative
trước khi tôi có thể xác định Monad
một.
Đây không phải là một rant. Tôi đã viết rất nhiều vì nếu không điều này sẽ nhanh chóng được đánh dấu là "quá rộng" hoặc "không rõ ràng". Câu hỏi đặt ra tiêu đề. Tôi biết (ít nhất là tôi khá chắc chắn) rằng có một số lý do lý thuyết cho điều này, vì vậy tôi tự hỏi những gì chính xác là những lợi ích ở đây.
Như một câu hỏi phụ, tôi muốn hỏi nếu có giải pháp thay thế khả thi mà vẫn giữ tất cả (hoặc hầu hết) những lợi thế, nhưng cho phép những gì tôi đã viết.
Bổ sung: Tôi nghi ngờ một trong những câu trả lời có thể là thứ gì đó dọc theo dòng "Nếu loại của tôi là Wrapper
, nhưng tôi không muốn sử dụng dụ Monad
ngụ ý?". Điều này tôi hỏi, tại sao không thể trình biên dịch chỉ cần chọn một trong những cụ thể nhất? Nếu có instance Monad MyType
, chắc chắn nó cụ thể hơn instance Wrapper a => Monad a
.
'unwrap' mô tả hành vi mà không có phương thức nào của' Monad' thực hiện; nếu không phải như vậy, 'unwrap' sẽ cho phép bạn trích xuất một' a' từ một tính toán 'IO a' (như' unsafePerformIO' làm), điều này sẽ đánh bại mục đích của việc có một đơn vị 'IO' trong lần đầu tiên địa điểm. Một lớp chỉ có thể ít mạnh hơn/biểu cảm hơn các lớp con của nó. – Jubobs
Điều gì sẽ là định nghĩa của 'unwrap' cho' Nothing' khi định nghĩa cá thể cho kiểu 'Maybe'? – Sibi
@Sibi Đơn giản, không có trường hợp nào cho Có thể. Tôi không nghĩ anh ta đã tuyên bố. Ngoài ra, tôi nghi ngờ Wrapper ngụ ý Monad mà không có bất kỳ luật nào (ngoài những luật tự do) trên đó. – Cubic