Минималистичный пример использования 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 в виде простой библиотеки, если у вас есть немного времени.

* Название такой конструкции - "молния"

Другие вопросы по тегам