Монада Пауза
Monads может делать много удивительных, безумных вещей. Они могут создавать переменные, которые содержат суперпозицию значений. Они могут позволить вам получить доступ к данным из будущего, прежде чем вы их вычислите. Они могут позволить вам писать разрушительные обновления, но не совсем. И тогда монада продолжения позволяет в разбить умы людей! Обычно твоя собственная. ; -)
Но вот проблема: вы можете сделать монаду, которая может быть Пауза?
data Pause s x instance Monad (Pause s) mutate :: (s -> s) -> Pause s () yield :: Pause s () step :: s -> Pause s () -> (s, Maybe (Pause s ()))
ThePause
монада - это своего рода государственная монада (следовательно,mutate
, с очевидной семантикой). Обычно такая монада имеет какую-то функцию «выполнения», которая выполняет вычисления и возвращает вам конечное состояние. НоPause
отличается: он обеспечиваетstep
функция, которая выполняет вычисления, пока не вызовет магическийyield
функция. Здесь вычисление приостанавливается, возвращая вызывающей стороне достаточно информации, чтобы возобновить вычисление позже.
Для дополнительного удивления: позвольте вызывающему абоненту изменять состояние междуstep
звонки. (Типовые сигнатуры выше должны позволять это, например.)
Использовать случай: часто легко написать код, который делает что-то сложное, но в целом PITA, чтобы преобразовать его такжевыхо промежуточные состояния в его работе. Если вы хотите, чтобы пользователь могменят что-то посередине исполнения, все становится очень быстро.
Идеи воплощения:
Очевидно это можно сделать с помощью потоков, блокировок иIO
. Но можем ли мы сделать лучше? ; -)
Что-то безумное с продолжением монады?
Может быть, какая-то писательская монада, гдеyield
просто записывает текущее состояние, и тогда мы можем «притвориться» наstep
это путем перебора состояний в журнале. (Очевидно, что это исключает изменение состояния между шагами, поскольку сейчас мы ничего не «приостанавливаем».)