Với hai monads, Monad m
và Monad n
, tôi muốn chuyển đổi m (n a)
thành n (m a)
. Nhưng dường như không có cách nào chung vì cả hai giao dịch (>>=)
và return
chỉ có một loại đơn vị và mặc dù (>>=)
cho phép trích xuất nội dung từ một đơn vị, bạn phải đóng gói lại thành cùng một loại đơn nguyên để có thể là giá trị kết quả.Đóng gói lại các monads - bất kỳ cách thức chung nào?
Tuy nhiên, nếu chúng tôi đặt m
thành loại cố định, công việc trở nên dễ dàng. Hãy Maybe
làm ví dụ:
reorder :: (Monad n) => Maybe (n a) -> n (Maybe a)
reorder Nothing = return Nothing
reorder (Just x) = do
x' <- x
return $ Just x'
Hoặc một danh sách:
reorder :: (Monad n) => [n a] -> n [a]
reorder [] = return []
reorder (x:xs) = do
x' <- x
xs' <- reorder xs
return (x':xs')
Không khó để thấy, chúng tôi đã có một mô hình ở đây. Để được rõ ràng hơn, hãy viết nó trong một cách Applicative
, và nó không có gì hơn việc áp dụng các nhà xây dựng dữ liệu cho mỗi phần tử:
reorder (Just x) = Just <$> x
reorder (x:xs) = (:) <$> x <*> (reorder xs)
Câu hỏi của tôi là: làm một typeclass Haskell đã tồn tại để mô tả các hoạt động đó, hay tôi phải tự mình phát minh ra bánh xe?
Tôi đã tìm kiếm ngắn gọn trong tài liệu GHC và không thấy gì hữu ích cho chủ đề này.
Điều này, tất nhiên, chỉ hoạt động khi hàm tạo bên ngoài của bạn là một 'Traversable' (không phải tất cả' Monad 'là). Tiền thưởng là phần bên trong chỉ phải là 'Áp dụng'. –