简体   繁体   中英

Implement undo and redo functions using a stack. How to edit a stack without having to recreate it in Haskell

I have a custom datatype called TextFile which stores four strings and I need to be able to store a version of it in a stack each time the text file is edited. This is so that I can implement some form of Undo and redo function.

However, the stack will be updated from within other functions and without creating a new stack each time, I can't see a way to save the changes when I push something to it?

Is there a way that I could create a stack and update that same stack each time something is pushed or popped from it?

newtype Stack a = Stack [a] deriving (Eq, Show)
buffer = Stack [] :: Stack TextFile

data TextFile = TextFile String String String String deriving Show
file = TextFile "This is the left element" " This is the right element" "" ""

pop :: Stack a -> (Maybe a, Stack a)
pop (Stack (x:xs)) = (Just x, Stack xs)
pop (Stack []) = (Nothing, Stack [])

push :: a -> Stack a -> Stack a
push x (Stack xs) = Stack (x:xs)

To clarify, my main question is if you can't change a variable's value in Haskell, how do you create a stack as a structure without duplicating it?

how do you create a stack as a structure without duplicating it?

The code you have presented is fine and will not duplicate much data.

Let's say you have a current stack of stack1 = a - b - c - d - e . And now you pop stack1 with the code:

pop (Stack (x:xs)) = (Just x, Stack xs)

You will return a new stack stack2 = b - c - d - e which is just the entire structure after the a and nothing is copied. If you keep stack1 around then you'd have two structures that look something like this:

 stack1 -> a - b - c - d - e
               ^
               |
             stack2

Bear in mind the singly linked list you're using means a is not part of stack2 . If stack1 is garbage collected then you'll end up with stack2 = b - c - d - e as you'd expect.

Now let's say you push z stack2 yielding stack3 = z - b - c - d - e . If stack1 and stack2 are still live then the heap would look something like:

     stack3 -> z
               |
 stack1 -> a - b - c - d - e
               ^
               |
             stack2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM