Hãy nhớ rằng các vòng như thế này trong Haskell không phải là phép thuật ... chúng chỉ là những thứ hạng nhất bình thường mà bạn có thể tự viết.
Đối với những gì nó đáng giá, tôi không nghĩ rằng nó quá hữu ích khi nghĩ về MaybeT
như một biến áp Monad. Với tôi, MaybeT
chỉ là trình bao bọc newtype để thực hiện thay thế (>>=)
... giống như cách bạn sử dụng Product
, Sum
, First
, And
, v.v ... để thực hiện thay thế mappend
và mempty
.
Ngay bây giờ, (>>=)
dành cho bạn là IO a -> (a -> IO b) -> IO b
. Nhưng sẽ hữu ích hơn khi có (>>=)
ở đây là IO (Maybe a) -> (a -> IO (Maybe b) -> IO (Maybe b)
. Ngay sau khi bạn nhận được hành động đầu tiên trả về một số Nothing
, thật sự không thể "ràng buộc" thêm nữa. Đó chính xác là những gì MaybeT
mang đến cho bạn. Bạn cũng có một "trường hợp tùy chỉnh" của guard
, guard :: Bool -> IO (Maybe a)
, thay vì guard :: IO a
.
forM_ [1..100] $ \i -> runMaybeT $ do
a <- lift doSomeIO
guard (isValid1 a)
b <- lift $ doSomeOtherIO a
guard (isValid2 b)
...
và đó là nó :)
MaybeT
không phải là ma thuật, hoặc, và bạn có thể đạt được về cơ bản tác dụng tương tự bằng cách sử dụng lồng nhau when
s. Đó là không cần thiết, nó chỉ làm cho mọi thứ đơn giản hơn và sạch hơn :)
Nguồn
2015-09-26 02:55:08
Có một vài gói trên Hackage cung cấp vòng của các loại khác nhau. Điều thú vị nhất tôi từng thấy có lẽ là https://hackage.haskell.org/package/loops – dfeuer
Biến thế Monad không bao giờ cần thiết - chỉ đơn giản là thuận tiện. –