在haskell中将堆栈创建为抽象数据类型

在haskell中将堆栈创建为抽象数据类型,haskell,Haskell,我需要在haskell中创建堆栈数据类型,以便能够这样编写: let a = emptyStack push 10 a //[10] pop a [] ghci> :t (:) (:) :: a -> [a] -> [a] emptyStack :: Stack a emptyStack = [] 我想要看起来像 push :: a -> Stack a -> Stack a push a b = a:b 但是我在语法方面有问题,确切地说是如何声明这个

我需要在haskell中创建堆栈数据类型,以便能够这样编写:

let a = emptyStack

push 10 a
//[10]

pop a 
[]
ghci> :t (:)
(:) :: a -> [a] -> [a]
emptyStack :: Stack a
emptyStack = []
我想要看起来像

push :: a -> Stack a -> Stack a
push a b = a:b
但是我在语法方面有问题,确切地说是如何声明这个新的数据类型,所以

let a = emptyStack 
:t a
将显示堆栈


关于语法的任何提示

让我们看看您的
push
实现。它使用运算符
。您可以通过以下方式找到该运算符的类型:

let a = emptyStack

push 10 a
//[10]

pop a 
[]
ghci> :t (:)
(:) :: a -> [a] -> [a]
emptyStack :: Stack a
emptyStack = []
因此,该运算符获取一个
a
(表示任意类型)和一个
a
s序列,并返回更新后的序列。因此,您的类型
Stack
需要是一个序列

type Stack a = [a]
然后,如果您这样定义emptyStack:

let a = emptyStack

push 10 a
//[10]

pop a 
[]
ghci> :t (:)
(:) :: a -> [a] -> [a]
emptyStack :: Stack a
emptyStack = []
你会得到你想要的结果

ghci> :t a
a :: Stack a

有了这些帮助,我想您将能够了解如何编写
pop

让我们看看您的
push
实现。它使用运算符
。您可以通过以下方式找到该运算符的类型:

let a = emptyStack

push 10 a
//[10]

pop a 
[]
ghci> :t (:)
(:) :: a -> [a] -> [a]
emptyStack :: Stack a
emptyStack = []
因此,该运算符获取一个
a
(表示任意类型)和一个
a
s序列,并返回更新后的序列。因此,您的类型
Stack
需要是一个序列

type Stack a = [a]
然后,如果您这样定义emptyStack:

let a = emptyStack

push 10 a
//[10]

pop a 
[]
ghci> :t (:)
(:) :: a -> [a] -> [a]
emptyStack :: Stack a
emptyStack = []
你会得到你想要的结果

ghci> :t a
a :: Stack a
有了这些帮助,我想您将能够了解如何编写
pop

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解决方案相反)。一个或另一个aproach是有效的(在某些情况下,一个会比另一个好,反之亦然)。

您可以编写

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解决方案相反)。一个或另一个aproach是有效的(在某些情况下,一个会比另一个好,反之亦然)。

那么抽象数据类型是使用“type”创建的吗?“数据”关键字呢?
类型
关键字创建类型同义词,即在本例中,
堆栈a
[a]
是完全等效的类型<代码>数据,OTOH,创建了新的实数类型,也就是说,
数据栈a=Stack[a]
不同于普通的
[a]
。所以抽象数据类型是使用“type”创建的吗?“数据”关键字呢?
类型
关键字创建类型同义词,即在本例中,
堆栈a
[a]
是完全等效的类型<代码>数据,oth,创建了新的实数类型,也就是说,
数据堆栈a=Stack[a]
不同于普通的
[a]
。我会在这里使用
新类型
newtype
而不是
data
不会产生运行时开销;事实上,它正是为这种情况而设计的。我会在这里使用
newtype
newtype
而不是
data
不会产生运行时开销;事实上,它正是针对这种情况而设计的。此页面有一个很好的最小堆栈实现:此页面有一个很好的最小堆栈实现: