Я ищу трансформатор монады, который можно использовать для отслеживания хода выполнения процедуры. Чтобы объяснить, как он будет использоваться, рассмотрите следующий код:
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 ()
Я понимаю, что step
должен существовать явно из-за монадических законов и что task
должен иметь явный параметр числа шагов из-за программного детерминизма/проблемы остановки.
Монада, как описано выше, может, как я вижу, быть реализована одним из двух способов:
- Через функцию, которая возвращает текущий стек имени задачи/шага индекса, и продолжение в процедуре в той точке, в которой она была остановлена. Повторное вызов этой функции в возвращаемом продолжении завершит выполнение процедуры.
- Через функцию, которая приняла действие, описывающее, что делать, когда шаг задачи завершен. Процедура будет выполняться неуправляемо до тех пор, пока она не будет завершена, "уведомляя" об окружающей среде об изменениях через предоставленное действие.
Для решения (1) я рассмотрел Control.Monad.Coroutine
с функтором подвески Yield
. Для решения (2) я не знаю каких-либо уже доступных монадных трансформаторов, которые были бы полезны.
Решение, которое я ищу, не должно иметь слишком больших служебных расходов и позволяет как можно больше контролировать процедуру (например, не требует доступа к IO или что-то еще).
Вызывает ли одно из этих решений жизнеспособность или есть другие решения этой проблемы где-то уже? Эта проблема уже решена с помощью трансформатора монады, который мне не удалось найти?
EDIT: Цель состоит не в том, чтобы проверить, выполнены ли все этапы. Цель состоит в том, чтобы "контролировать" процесс во время его работы, чтобы можно было узнать, сколько из него было выполнено.