La mónada Pausa
Las mónadas pueden hacer muchas cosas increíbles y locas. Pueden crear variables que contienen una superposición de valores. Pueden permitirle acceder a datos del futuro antes de computarlos. Pueden permitirte escribir actualizaciones destructivas, pero no realmente. Y luego la mónada de continuación te permiteromper las mentes de las personas! Usualmente tu propio. ;-)
Pero aquí hay un desafío: ¿Puedes hacer una mónada que pueda seren pausa?
data Pause s x instance Monad (Pause s) mutate :: (s -> s) -> Pause s () yield :: Pause s () step :: s -> Pause s () -> (s, Maybe (Pause s ()))
losPause
La mónada es un tipo de mónada estatal.mutate
, con la semántica obvia). Normalmente, una mónada como esta tiene algún tipo de función de "ejecución", que ejecuta el cálculo y le devuelve el estado final. PeroPause
es diferente: proporciona unastep
Función, que ejecuta el cálculo hasta que llama al mágico.yield
función. Aquí el cálculo se detiene, devolviendo a la persona que llama la información suficiente para reanudar el cálculo más tarde.
Para mayor seguridad: permita que la persona que llama modifique el estado entrestep
llamadas (Las firmas de tipo anteriores deberían permitir esto, por ejemplo).
Caso de uso: a menudo es fácil escribir código que hace algo complejo, pero un PITA total para transformarlo tambiénsalida Los estados intermedios en su funcionamiento. Si quieres que el usuario puedacambio algo a mitad de la ejecución, las cosas se complican realmente rápido.
Ideas de implementación:
Obviamente Se puede hacer con hilos, cerraduras yIO
. ¿Pero podemos hacerlo mejor? ;-)
¿Algo loco con una mónada de continuación?
Tal vez algún tipo de mónada escritor, dondeyield
simplemente registra el estado actual, y luego podemos "simular"step
iterando sobre los estados en el registro. (Obviamente, esto impide alterar el estado entre pasos, ya que no estamos "pausando" nada en este momento).