Allgemeines Thema: Während ich finde, dass die Idee, Monaden zusammen zu stapeln, sehr ansprechend ist, habe ich eine Menge Probleme damit, sich vorzustellen, wie der Code ausgeführt wird und welche Befehle die Schichten ausführen sollen. Im Folgenden finden Sie ein Beispiel für einen Stapel: Writer, State, State und Error in keiner bestimmten Reihenfolge (oder?).Wie beurteilen Sie die Reihenfolge der Ausführung von Funktionen in einem MonadT-Stack?
-----------------------
-- 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"
Bitte beachten Sie in mStack
, ob ein Fehler ausgelöst wird oder nicht, hat nichts mit irgendeinem anderen Teil der Funktion zu tun.
nun idealerweise möchte ich die Ausgabe wie folgt aussehen:
(Right 100, 1, "accessed memory", fromList [...])
oder allgemein:
(output of errorT, output of stateT Counter, output of writerT, output of StateT Memory)
Aber ich kann es nicht zu arbeiten. Insbesondere ich versuchte mit dem Stapel als ob Fehler auf der äußerste Schicht ist:
mem1 = M.fromList [("x",10),("y",5)]
runIdentity $ runWriterT (runStateT (runStateT (runErrorT mStack) 0) mem1) ""
Aber mir diese Fehlermeldung bekommen:
Couldn't match type `Int' with `Map [Char] Int'
Die obige Instanz zur Seite, in der Regel, wenn ich nennt:
runMonadT_1 (runMonadT_2 expr param2) param1
,
sind die im Zusammenhang Funktionen monadT_2
zuerst ausgeführt, dann wird dieser Ausgang in die Funktionen bezüglich monadT_1
geleitet? Mit anderen Worten, so zwingend der Code in der obigen Funktion mStack
aussieht, hängt die Reihenfolge der Ausführung vollständig von der Reihenfolge ab, in der die monadT ausgeführt wird (abgesehen von jeglicher Starrheit in der Struktur, die durch lift
eingeführt wurde)?