Sto cercando un trasformatore monad che può essere utilizzato per tracciare l'avanzamento di una procedura. Per spiegare come sarebbe stato utilizzato, si consideri il seguente codice:Trasformatore Monad per il monitoraggio dell'avanzamento
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()
mi rendo conto che step
deve esistere in modo esplicito a causa delle leggi monadici, e che task
deve avere un esplicito parametro numero di passo a causa del programma di determinismo/il problema dell'arresto.
La monade come sopra descritto potrebbe, secondo me, essere implementata in due modi:
- Via una funzione che restituirà la pila cognomi compito/passo attuale, e una continuazione nel procedura nel punto in cui era stata interrotta. Chiamando ripetutamente questa funzione sulla continuazione restituita si completerebbe l'esecuzione della procedura.
- Tramite una funzione che ha intrapreso un'azione descrivendo cosa fare quando una fase di attività è stata completata. La procedura funzionerebbe in modo incontrollabile fino al completamento, "notifica" all'ambiente delle modifiche tramite l'azione fornita.
Per la soluzione (1), ho visto Control.Monad.Coroutine
con il functor di sospensione Yield
. Per la soluzione (2), non conosco alcun trasformatore monad già disponibile che sarebbe utile.
La soluzione che sto cercando non dovrebbe avere troppe prestazioni in testa e consentire il massimo controllo sulla procedura possibile (ad esempio non richiede l'accesso IO o qualcosa del genere).
Una di queste soluzioni è valida, oppure esistono già altre soluzioni a questo problema? Questo problema è già stato risolto con un trasformatore monad che non sono stato in grado di trovare?
MODIFICA: L'obiettivo non è controllare se tutti i passaggi sono stati eseguiti. L'obiettivo è essere in grado di "monitorare" il processo mentre è in esecuzione, in modo che si possa dire quanto di esso è stato completato.
You continuazioni citate ... Forse mi manca qualcosa di ovvio, ma mi chiedo se potessi semplicemente usare il c ontinuation monad transformer 'ContT'. – mergeconflict
A meno che non abbia reimplementato 'putStr' e' putStrLn' con tipi 'String -> ProgressT IO()', è necessario sollevarli. Usa 'liftIO' per fare ciò. –
La produzione e la visualizzazione delle informazioni sullo stato di avanzamento è un sistema di pubblicazione/sottoscrizione. Come implementarlo sotto il cofano dipenderà dal fatto che il thread principale o uno speciale altro thread o molti altri thread agiranno sullo stato di avanzamento. –