Tema generale: Mentre trovo che l'idea di impilare le monadi sia molto allettante, ho molti problemi a immaginare come viene eseguito il codice e quali sono gli ordini appropriati per eseguire i livelli. Di seguito è riportato un esempio di stack: Writer, State, State ed Error, in nessun ordine particolare (o c'è?).Come si ragiona sull'ordine di esecuzione delle funzioni in uno stack 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"
Si prega di notare in mStack
, se viene generato un errore o no non ha nulla a che fare con qualsiasi altra parte della funzione.
Ora idealmente voglio l'uscita a guardare come questo:
(Right 100, 1, "accessed memory", fromList [...])
o in generale:
(output of errorT, output of stateT Counter, output of writerT, output of StateT Memory)
Ma non riesco a farlo funzionare. In particolare, ho provato a fare funzionare la pila come se l'errore è lo strato più esterno:
mem1 = M.fromList [("x",10),("y",5)]
runIdentity $ runWriterT (runStateT (runStateT (runErrorT mStack) 0) mem1) ""
Ma sto ottenendo questo messaggio di errore:
Couldn't match type `Int' with `Map [Char] Int'
È possibile che questo esempio a parte, in generale, quando ho chiamo:
runMonadT_1 (runMonadT_2 expr param2) param1
,
sono le funzioni relative a monadT_2
viene eseguito per primo, quindi quell'output viene collegato alle funzioni relative a monadT_1
? Quindi, in altre parole, per quanto il codice appaia imperativo nella funzione di cui sopra mStack
, l'ordine di esecuzione dipende interamente dall'ordine in cui viene eseguito il monadT (oltre a qualsiasi rigidità nella struttura introdotta da lift
)?