繁体   English   中英

使用堆栈实现撤消和重做功能。 如何编辑堆栈而不必在Haskell中重新创建它

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

我有一个名为TextFile的自定义数据类型,它存储了四个字符串,每次编辑文本文件时,我都需要能够将它的一个版本存储在一个堆栈中。 这样我就可以实现某种形式的撤销和重做功能。

但是,堆栈将从其他函数中更新,而不是每次都创建一个新的堆栈,当我向它推送东西时,我看不到保存更改的方法?

是否有一种方法可以创建堆栈并在每次推送或弹出某个堆栈时更新相同的堆栈?

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)

为了澄清,我的主要问题是如果你不能在Haskell中改变一个变量的值,你如何创建一个堆栈作为一个结构而不重复它?

如何创建一个堆栈作为一个结构而不重复它?

您提供的代码很好,不会复制太多数据。

假设你有一堆stack1 = a - b - c - d - e 现在你用代码pop stack1

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

你将返回一个新的堆栈stack2 = b - c - d - e ,它只是a之后的整个结构,没有任何复制。 如果你保持stack1,那么你有两个看起来像这样的结构:

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

请记住你使用手段单向链表a不是一部分stack2 如果stack1被垃圾收集,那么你最终会得到stack2 = b - c - d - e正如你所期望的那样。

现在让我们说你push z stack2产生stack3 = z - b - c - d - e 如果stack1stack2仍然存在,那么堆将看起来像:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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