标准列表 ( [a]
) 允许您在列表末尾快速插入并从列表末尾快速删除。
假设我们可以push
为它创建一个“类似列表”的类型和一个函数,以保持“快速”添加的第一个元素可用,以便我们可以有效地循环从最旧到最新的队列:
data Queue a = Empty | Element a (Queue a)
push :: a -> Queue a -> Queue a
push a Empty = Element a Empty
push a (Value b pointer) = Element b (push a pointer)
但是有一个明显的缺点——添加一个新元素时,它会递归地“深入”到队列中,即随着队列的增长,新添加的速度会越来越慢。
本质上,这是一个问题——如何在 Haskell 中实现一个容器FIFO
,以便您可以快速添加一个新元素并快速从中读取,从旧元素开始?
队列可以使用两个堆栈来组织,它们可以用作相同的列表。排队时间是常数,检索时间是摊销常数。那些。单个提取操作可能需要很长时间,但所有操作的平均时间将保持不变。
您也可以为此目的使用容器
Seq
。它提供了对序列开头和结尾的有效访问,并使用tree实现。我不禁注意到您的类型
Queue
完全重复了内置类型的结构[]
。出于学习目的,使用此类类型是可以接受的,但在实践中,使用内置列表会更有效,newtype
必要时可以选择将其包装起来。当然,尽管内置列表和您的列表都不
Queue
适合高效实现队列。