Минималистичный пример использования Undo Monad Transformer
Я искал в Интернете учебники / примеры того, как использовать Undo Monad Transformer, но не нашел ни одного.
Может ли кто-нибудь привести пример минимализма, который показывает, как его использовать?
Или указание на книгу, где это объясняется, также будет полезно.
Я хотел бы использовать его для реализации операций отмены / возврата в простом редакторе.
1 ответ
Я также не могу найти учебники, но думаю, что понимаю это достаточно хорошо, чтобы объяснить.
Сначала нам нужно собрать воедино тип для представления текущего состояния наших редакторов, а пока просто сделаем
type EditorState = Int
Тогда мы можем дать это нашему Undo
монада
type Editor = Undo EditorState
Теперь мы можем сделать что-то вроде
fakeUser = do
put 1 -- Current state is 1
put 2 -- Current state is 2, 1 is saved in undo buffer
put 3 -- Current state is 3, 1 and 2 are saved
undo -- Move 3 to redo buffer, pop 2 off of undo buffer, current state is 2
redo -- reverse of the above, current state is 3
Таким образом, вы можете думать об этом как о курсоре в списке *, и мы можем перемещаться вперед и назад в этом списке, где движение влево означает, что мы "отменяем" вещи, а движение вправо означает, что мы "переделываем" вещи. С помощью put
вставляет элемент в список в текущей точке и перемещает старый элемент в буфер отмены.
Я бы порекомендовал не полагаться на MonadState
экземпляр делать вставки, потому что он слишком много намекает на внутренние Undo
и это усложняет ситуацию, если мы хотим отслеживать другое состояние через наш редактор.
Тем не менее, это довольно простой кусок кода, который вы можете обновить, чтобы не использовать MonadState
, избавиться от контекста типа данных, удалить зависимость от -f-glasgow-extensions
который осуждается и затем загружается в hackage в виде простой библиотеки, если у вас есть немного времени.
* Название такой конструкции - "молния"