Kombinationsstatus mit E / A-Aktionen

Angenommen, ich habe eine staatliche Monade wie:

data Registers = Reg {...}

data ST = ST {registers :: Registers,
              memory    :: Array Int Int}

newtype Op a = Op {runOp :: ST -> (ST, a)}

instance Monad Op where
 return a    = Op $ \st -> (st, a)
 (>>=) stf f = Op $ \st -> let (st1, a1) = runOp stf st
                               (st2, a2) = runOp (f a1) st1
                            in (st2, a2)

with funktioniert wie

getState :: (ST -> a) -> Op a
getState g = Op (\st -> (st, g st)

updState :: (ST -> ST) -> Op ()
updState g = Op (\st -> (g st, ()))

und so weiter. Ich möchte verschiedene Operationen in dieser Monade mit IO-Aktionen kombinieren. Ich könnte also entweder eine Evaluierungsschleife schreiben, in der Operationen in dieser Monade ausgeführt werden und eine E / A-Aktion mit dem Ergebnis ausgeführt wird, oder ich denke, ich sollte in der Lage sein, Folgendes zu tun:

newtype Op a = Op {runOp :: ST -> IO (ST, a)}

Printing-Funktionen hätten den Typ Op (), und andere Funktionen hätten den Typ Op a, z. B. könnte ich ein Zeichen vom Terminal mit einer Funktion vom Typ IO Char lesen. Ich bin mir jedoch nicht sicher, wie eine solche Funktion aussehen würde, da beispielsweise das Folgende nicht gültig ist.

runOp (do x <- getLine; setMem 10 ... (read x :: Int) ... ) st

since getLine hat den Typ IO Char, aber dieser Ausdruck hätte den Typ Op Char. Kurz gesagt, wie würde ich das machen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage