Um meine Fähigkeiten in Haskell zu testen, entschied ich, dass ich das allererste Spiel implementieren wollte, das Sie in Land of Lisp / Reich der Schläger finden. Das "Raten Sie meine Nummer" Spiel. Das Spiel benötigt einen veränderbaren Status, da es ständig die oberen und unteren Grenzen aktualisieren muss, damit das Programm den Wert, an den der Benutzer denkt, einholen kann.
Es geht ein bisschen so:
%Vor% Nun, so etwas ist meines Wissens in Haskell nicht ganz möglich, indem es eine Funktion der REPL aufruft, die den globalen veränderlichen Zustand modifiziert, und das Ergebnis unmittelbar danach ausdruckt, da es gegen das Prinzip der Unveränderlichkeit verstößt. Daher muss die gesamte Interaktion innerhalb einer IO
und / oder State
monad liegen. Und da stecke ich fest.
Ich kann nicht in der Lage sein, mich daran zu erinnern, die IO
monad und die State
monad zu kombinieren, damit ich Input, Ergebnisse und Status in derselben Funktion erhalten kann.
Folgendes habe ich bis jetzt:
%Vor%Alles, was ich jetzt tun muss, ist einen Weg zu finden
Wie kombiniere ich IO
und State
auf elegante Weise, um dies zu erreichen?
Hinweis: Ich bin mir bewusst, dass dies wahrscheinlich ohne die Verwendung von Staat überhaupt erreicht werden kann; aber ich möchte, dass es dem Original treu bleibt
Sie können verschiedene Monaden mit Hilfe von Monade-Transformatoren kombinieren - in diesem Fall StateT
. Sie können Ihren vorhandenen Code verwenden, indem Sie die Typignaturen so ändern, dass StateT
:
Dann können Sie eine Funktion schreiben, um das Spiel mit einem Zustandsparameter auszuführen:
%Vor% Sie verwenden liftIO
, um eine IO
Aktion in die StateT Bound IO
Monade zu heben, damit Sie zur Eingabe auffordern und die nächste Zeile lesen können.
Schließlich kannst du das Spiel mit runStateT
:
Sie müssen in diesem Beispiel die Zustandsmonade überhaupt nicht verwenden. Hier ist ein Beispiel, das den Status als Parameter übergibt:
%Vor%Ansonsten suchen Sie nach Monadetransformatoren . Zum Beispiel mit StateT:
%Vor%Sehen Sie dieses Kapitel von Real World Haskell für ein Tutorial zum Thema Monadetransformatoren.
Hier ist eine Lösung mit dem StateT
-Transformator. Bemerkenswerte Punkte:
getLine
anstelle der REPL. liftIO
zu irgendwelchen IO-Aktionen hinzufügen müssen. runStateT
aus, wobei Sie auch den Anfangszustand angeben. Das Programm:
%Vor%Tags und Links haskell state-monad io-monad