我需要在haskell中创建堆栈数据类型,以便能够像这样写:
let a = emptyStack
push 10 a
//[10]
pop a
[]
我希望推送看起来像
push :: a -> Stack a -> Stack a
push a b = a:b
但我的语法有问题,究竟如何声明这种新的数据类型,以便
let a = emptyStack
:t a
会显示Stack
语法
的任何提示答案 0 :(得分:4)
让我们看看push
的实施情况。它使用运算符:
。您可以像这样找到该运算符的类型:
ghci> :t (:)
(:) :: a -> [a] -> [a]
因此,此运算符采用a
(表示任意类型)和a
s序列,并返回更新的序列。因此,您的类型Stack
必须是一个序列。
type Stack a = [a]
如果你然后像这样定义emptyStack:
emptyStack :: Stack a
emptyStack = []
你会得到你正在寻找的结果。
ghci> :t a
a :: Stack a
有了这个帮助,我想你将能够弄清楚如何写pop
。
答案 1 :(得分:3)
你可以写
import Data.Maybe
data Stack a = Stack [a] deriving Show
empty :: Stack a
empty = Stack []
push :: a -> Stack a -> Stack a
push x (Stack xs)= Stack (x:xs)
pop :: Stack a -> (Maybe a, Stack a)
pop (Stack []) = (Nothing, Stack [])
pop (Stack (x:xs)) = (Just x, Stack xs)
例如
*Main> push 4 $ push 3 empty
Stack [4,3]
*Main> pop $ push 4 $ push 3 empty
(Just 4,Stack [3])
这个方法是严格检查类型参数(与@mhwombat解决方案相反)。一个或其他方法是有效的(在某些情况下一个会好于其他情况,反之亦然)。