Chủ đề chung: Trong khi tôi tìm thấy ý tưởng sắp xếp các monads với nhau rất hấp dẫn, tôi gặp rất nhiều rắc rối khi xem mã được thực hiện như thế nào và các lệnh thích hợp để chạy các lớp là gì. Dưới đây là một ví dụ về một ngăn xếp: Writer, State, State, và Error, không theo thứ tự cụ thể (hoặc là có?).Làm thế nào để bạn lý do về thứ tự thực hiện các chức năng trong một ngăn xếp monadT?
-----------------------
-- Utility Functions --
-----------------------
type Memory = Map String Int
type Counter = Int
type Log = String
tick :: (MonadState Counter m) => m()
tick = modify (+1)
record :: (MonadWriter Log m) => Log -> m()
record msg = tell $ msg ++ "; "
------------------
-- MonadT Stack --
------------------
mStack :: (MonadTrans t, MonadState Memory m, MonadState Counter (t m), MonadError ErrMsg (t m), MonadWriter Log (t m)) => t m Int
mStack = do
tick
m <- lift get
let x = fromJust (M.lookup "x" m) in x
record "accessed memory"
case True of
True -> return 100
False -> throwError "false"
Hãy lưu ý trong mStack
, cho dù lỗi được ném hoặc không liên quan gì đến bất kỳ phần nào khác của hàm.
Bây giờ lý tưởng tôi muốn đầu ra trông như thế này:
(Right 100, 1, "accessed memory", fromList [...])
hoặc nói chung:
(output of errorT, output of stateT Counter, output of writerT, output of StateT Memory)
Nhưng tôi không thể có được nó để làm việc. Cụ thể, tôi đã cố gắng chạy stack như nếu Lỗi là trên lớp ngoài cùng:
mem1 = M.fromList [("x",10),("y",5)]
runIdentity $ runWriterT (runStateT (runStateT (runErrorT mStack) 0) mem1) ""
Nhưng tôi nhận được thông báo lỗi này:
Couldn't match type `Int' with `Map [Char] Int'
Các ví dụ ở trên sang một bên, nói chung, khi tôi đang gọi:
runMonadT_1 (runMonadT_2 expr param2) param1
,
là các chức năng liên quan đến monadT_2
chạy trước, sau đó đầu ra đó được đưa vào các chức năng liên quan đến monadT_1
? Vì vậy, nói cách khác, như bắt buộc như mã nhìn vào các chức năng trên mStack
, là thứ tự thực hiện hoàn toàn phụ thuộc vào thứ tự mà monadT được chạy (ngoài bất kỳ cứng nhắc trong cấu trúc được giới thiệu bởi lift
)?