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