Có một vài vấn đề lớn ở đây.
Trước tiên, phiên bản Monad
phải có kind* -> *
. Điều đó có nghĩa là họ cần ít nhất một biến số , trong đó Something
của bạn không có bất kỳ biến nào. Để so sánh:
-- kind * -> *
Maybe
IO
Either String
-- kind *
Maybe Int
IO()
Either String Double
Xem cách mỗi Maybe
, IO
, và Either String
cần một tham số kiểu trước khi bạn có thể sử dụng chúng? Với Something
, không có chỗ cho các tham số kiểu để điền vào Vì vậy, bạn cần phải thay đổi định nghĩa của bạn để:.
data Something a = Something a
Vấn đề lớn thứ hai là các >>=
trong trường hợp đơn nguyên của bạn là sai. Nói chung, bạn không thể sử dụng ký hiệu vì nó chỉ gọi các hàm Monad
return
và >>=
. Vì vậy, bạn phải viết nó ra mà không có bất kỳ chức năng monad, hoặc là do-notation hoặc gọi >>=
hoặc return
.
instance Monad Something where
return a = Something a --Wraps a in 'Something'
(Something m) >>= f = f m --unwraps m and applies it to f
Định nghĩa của >>=
đơn giản hơn bạn mong đợi. Unwrapping m
thật dễ dàng vì bạn chỉ cần khớp mẫu trên hàm tạo Something
. Ngoài ra f :: a -> m b
, vì vậy bạn không cần phải lo lắng về việc gói nó lại, bởi vì f
thực hiện điều đó cho bạn.
Trong khi không có cách nào để mở một đơn lẻ nói chung, rất nhiều cụ thể đơn lẻ có thể được bỏ.
Lưu ý rằng không có gì sai về cú pháp khi sử dụng ký hiệu hoặc >>=
trong khai báo cá thể đơn lẻ. Vấn đề là >>=
được định nghĩa đệ quy để chương trình đi vào vòng lặp vô tận khi bạn cố gắng sử dụng nó.
(N.B. Something
như định nghĩa ở đây là Identity monad)
Đối với câu hỏi thứ ba của bạn, có những return
chức năng được xác định trong trường hợp đơn nguyên là một trong đó sẽ được gọi. Loại lớp được gửi theo loại, và như bạn đã chỉ định loại phải là Something b
trình biên dịch sẽ tự động sử dụng dụ Monad cho Something
. (Tôi nghĩ bạn có nghĩa là dòng cuối cùng là doMagicTo var
).
Điều này thật tuyệt. Tất cả những câu trả lời này đều rất tốt. Tôi cảm thấy bắt buộc phải nhận xét rằng cộng đồng Haskell cho đến nay là hữu ích và kỹ lưỡng nhất đối với bất kỳ tôi đã gặp phải. Cố lên các chàng trai. – providence