Estoy buscando un transformador de mónada que se pueda usar para rastrear el progreso de un procedimiento. Para explicar la forma en que se utilizaría, considere el siguiente código:Transformador de mónada para seguimiento de progreso
procedure :: ProgressT IO()
procedure = task "Print some lines" 3 $ do
liftIO $ putStrLn "line1"
step
task "Print a complicated line" 2 $ do
liftIO $ putStr "li"
step
liftIO $ putStrLn "ne2"
step
liftIO $ putStrLn "line3"
-- Wraps an action in a task
task :: Monad m
=> String -- Name of task
-> Int -- Number of steps to complete task
-> ProgressT m a -- Action performing the task
-> ProgressT m a
-- Marks one step of the current task as completed
step :: Monad m => ProgressT m()
que darse cuenta de que step
tiene que existir explícitamente debido a las leyes monádicos, y que task
tiene que tener un parámetro explícito número de paso a causa de determinismo programa/el problema de detenerse
La mónada como se describió anteriormente podría, tal como lo veo, ser implementado en una de dos maneras:
- través de una función que devuelva la pila índice de nombre de la tarea/paso actual, y una continuación en el procedimiento en el punto que lo dejó. Llamar a esta función repetidamente en la continuación devuelta completaría la ejecución del procedimiento.
- Mediante una función que realizó una acción que describe qué hacer cuando se completa un paso de la tarea. El procedimiento se ejecutaría incontrolablemente hasta que se completara, "notificando" al entorno sobre los cambios a través de la acción proporcionada.
Para la solución (1), he examinado Control.Monad.Coroutine
con el Yield
functor de suspensión. Para la solución (2), no conozco ningún transformador de mónada ya disponible que pueda ser útil.
La solución que estoy buscando no debe tener demasiada sobrecarga de rendimiento y permitir tanto control sobre el procedimiento como sea posible (por ejemplo, no requiere acceso a IO o algo así).
¿Alguna de estas soluciones parece viable o hay otras soluciones a este problema en alguna parte? ¿Este problema ya se ha resuelto con un transformador de mónada que no he podido encontrar?
EDITAR: El objetivo no es comprobar si se han realizado todos los pasos. El objetivo es poder "monitorear" el proceso mientras se está ejecutando, para que uno pueda decir cuánto se ha completado.
You continuaciones mencionadas ... Tal vez me esté perdiendo algo obvio, pero me pregunto si podría usar la c ontinuation monad transformer 'ContT'. – mergeconflict
A menos que vuelva a implementar 'putStr' y' putStrLn' con los tipos 'String -> ProgressT IO()', debe levantarlos. Use 'liftIO' para hacer esto. –
La producción y visualización de información de progreso es un sistema de publicación/suscripción. Cómo implementarlo bajo el capó dependerá de si el hilo principal o un hilo especial u otros hilos estarán actuando en el estado de progreso. –