Pop无法正常工作,堆栈始终为空
我一直在尝试在 Haskell 中实现一个 Stack 机器来完成大学工作,但我遇到了困难。当我尝试将一个值压入堆栈时,它总是只返回我刚刚压入的值。
module Stack(Stack, push, pop, top, stackEmpty, newStack) where
push :: t -> Stack t -> Stack t
pop :: Stack t -> Stack t
top :: Stack t -> t
stackEmpty :: Stack t -> Bool
newStack :: Stack t
data Stack t = Stk [t]
newStack = Stk []
push x (Stk xs) = (Stk (x : xs))
pop (Stk []) = error "retirada em pilha vazia"
pop (Stk (_ : xs)) = Stk xs
top (Stk []) = error "topo de pilha vazia"
top (Stk (x : _)) = x
stackEmpty (Stk []) = True
stackEmpty _ = False
instance (Show t) => Show (Stack t) where
show (Stk []) = "#"
show (Stk (x : xs)) = (show x) ++ "|" ++ (show (Stk xs))
如果我每次尝试在同一个堆栈中推送,就会发生这种情况,它会不断将值推送到一个空列表。我想这是因为我声明pilha为 anewStack并且 anewStack是一个空列表,所以每次我推送到它时它都会推送到一个空列表,对吗?问题是我不知道如何保存堆栈的值。
ghci> let pilha = newStack
ghci> push 5 pilha
5|#
ghci> push 6 pilha
6|#
ghci>
这就是我为它在终端中工作所做的
ghci> let oldStack = push 5 newStack
ghci> show oldStack
"5|#"
ghci> let newerStack = push 6 oldStack
ghci> show newerStack
"6|5|#"
ghci> newerStack = push 7 newerStack
ghci> show newerStack
"
我知道这就是逻辑,每次推送时我都需要创建一个新的Stack,它将使用旧堆栈中的值,但我似乎无法弄清楚如何对其进行编码。
回答
如果你写newerStack = push 7 newerStack,那么你newerStack根据自身定义,这意味着你会push 7 (push 7 (push 7 (…))),因此最终陷入无限循环。
因此,您应该将其实现为:
ghci> let stack1 = push 5 newStack
ghci> stack1
5|#
ghci> let stack2 = push 6 stack1
ghci> stack2
6|5|#
ghci> let stack3 = push 7 stack2
ghci> stack3
7|6|5|#