Die Pause-Monade

Monaden können viele erstaunliche, verrückte Dinge tun. Sie können Variablen erstellen, die eine Überlagerung von Werten enthalten. Mit ihnen können Sie auf Daten aus der Zukunft zugreifen, bevor Sie sie berechnen. Mit ihnen können Sie destruktive Updates schreiben, aber nicht wirklich. Und dann können Sie die Fortsetzung MonadeMenschen um den Verstand bringen! Normalerweise deine eigene. ;-)

Aber hier ist eine Herausforderung: Können Sie eine Monade machen, die sein kannhielt inne?

data Pause s x
instance Monad (Pause s)
mutate :: (s -> s) -> Pause s ()
yield :: Pause s ()
step :: s -> Pause s () -> (s, Maybe (Pause s ()))

DasPause Monade ist eine Art Staatsmonade (dahermutatemit der offensichtlichen Semantik). Normalerweise hat eine Monade wie diese eine Art "Run" -Funktion, die die Berechnung ausführt und Ihnen den Endzustand zurückgibt. AberPause ist anders: Es bietet einestep Funktion, die die Berechnung ausführt, bis sie das Magische aufruftyield Funktion. Hier wird die Berechnung angehalten und gibt dem Anrufer genügend Informationen zurück, um die Berechnung später fortzusetzen.

Für zusätzliche Erstaunlichkeit: Ermöglichen Sie dem Anrufer, den Status zwischen zu ändernstep Anrufe. (Die obigen Typensignaturen sollten dies beispielsweise ermöglichen.)

Anwendungsfall: Es ist oft einfach, Code zu schreiben, der etwas Komplexes tut, aber eine totale PITA, um es auch zu transformierenAusgabe die Zwischenzustände in ihrer Funktionsweise. Wenn Sie möchten, dass der Benutzer dies kannVeränderung Auf halbem Weg durch die Ausführung werden die Dinge sehr schnell komplex.

Umsetzungsideen:

Offensichtlich es kann mit Threads, Locks und gemacht werdenIO. Aber können wir es besser machen? ;-)

Etwas Wahnsinniges mit einer Fortsetzung Monade?

Vielleicht eine Art Schriftstellermonade, woyield protokolliert nur den aktuellen Zustand und dann können wir "so tun"step es durch Iterieren über die Zustände im Protokoll. (Dies schließt natürlich aus, den Status zwischen den Schritten zu ändern, da wir jetzt nicht wirklich irgendetwas "pausieren".)

Antworten auf die Frage(6)

Ihre Antwort auf die Frage