nehme ich einen Zustand Monade haben wie:Kombinieren Zustand mit IO Aktionen
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)
mit Funktionen 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. So konnte ich entweder eine Auswertung Schleife schreiben, in dem Operationen in diesem Monade durchgeführt wurden und eine IO-Aktion mit dem Ergebnis ausgeführt, oder, glaube ich, sollte ich in der Lage sein, etwas zu tun, wie folgt aus:
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, zB könnte ich mit einer Funktion vom Typ IO Char ein Zeichen vom Terminal lesen. Ich bin mir jedoch nicht sicher, wie eine solche Funktion aussehen würde, da beispielsweise das Folgende nicht gültig ist.
seit getLine hat Typ IO Char, aber dieser Ausdruck hätte Typ Op Char. Umreiß, wie würde ich das tun?
Ich erkenne (jetzt), dass die vorgestellte Lösung Standard ist, aber das ist eine sehr interessante (und elegante) Lösung. Es war sehr hilfreich, dass Sie meinen Code mit einem Monad-Transformer neu geschrieben haben, da er ein konkretes Beispiel lieferte. Vielen Dank! – danportin
Eine schöne pädagogische Ergänzung zu Martijns pragmatischer Lösung. –