haskell(模块)中队列的使用

haskell(模块)中队列的使用,haskell,module,queue,Haskell,Module,Queue,我有一个关于Haskell代码的问题: module Queue (Queue, emptyQueue, queueEmpty, enqueue, dequeue, front) where newtype Queue a = MakeQ([a]) emptyQueue :: Queue a emptyQueue = MakeQ([]) queueEmpty :: Queue a -> Bool queueEmpty (MakeQ(q)) = null q enqueue :: a

我有一个关于Haskell代码的问题:

module Queue (Queue, emptyQueue, queueEmpty, enqueue, dequeue, front) where

newtype Queue a = MakeQ([a])

emptyQueue :: Queue a
emptyQueue = MakeQ([])

queueEmpty :: Queue a -> Bool
queueEmpty (MakeQ(q)) = null q

enqueue :: a -> Queue a -> Queue a
enqueue x (MakeQ(q)) = MakeQ(q ++ [x])

dequeue :: Queue a -> Queue a
dequeue (MakeQ(x:q)) = MakeQ(q)

front :: Queue a -> a
front (MakeQ(x:q)) = x
我知道队列通常是如何工作的,以及每个操作的主要功能。我的第一个问题是,我不知道如何在拥抱中使用这些操作。如何创建空队列或在创建后将元素放入其中?我尝试了几个命令,但都产生了错误消息,即Make([])、emptyQueue[]。。。我知道这些命令非常幼稚,但我绝对不熟悉Haskell,只需要2周左右的时间

第二个问题是关于“MakeQ”本身。这只是我们行动的名称声明,对吗?还是一个静态Haskell命令?依我看,它也可能是“QQQ”或其他什么。我无法真正测试这是否会使程序崩溃,因为我不知道如何使用这个模块


即使我的问题看起来有点愚蠢,如果有人能给我一个解释或提示,我也会非常高兴…

emptyQueue
本身就是一个空队列;您不必向它传递任何参数

MakeQ
只是一个任意的名字,你是对的;它可以是任何东西(只要你改变了它的所有其他用途)。在这种情况下,它是
Queue
的构造函数:如果
xs
a
值的列表(即具有类型
[a]
),则
MakeQ xs
队列a
。但是,模块不导出
MakeQ
,因此您不能从外部使用它-它被用作实现的一部分,并且隐藏以维护抽象;它可以很容易地用另一种非列表结构重写,而不会破坏使用该模块的任何代码

队列上的操作不是通过更新现有队列来完成的,而是通过将队列转换为新队列来完成的。例如,如果
a
Int
,而
q
Queue Int
,那么
enqueue a q
是另一个
Queue Int
,后面添加了
a
。类似地,如果
q
Queue Int
,则
dequeue q
是另一个
Queue Int
,没有前面元素,
front q
是前面元素本身(一个
Int

此外,请注意,拥抱不再保持;您应该考虑安装基于GHC编译器的。它像Hugs一样包含一个“解释器”程序,所以它不仅仅是一个标准编译器

下面是一个示例,说明如何从交互式提示符使用此队列模块:

GHCi> let q = emptyQueue :: Queue Int
GHCi> let q1 = enqueue 42 q
GHCi> front q1
42
GHCi> let q2 = enqueue 43 q1
GHCi> front q2
43
GHCi> front (dequeue q2)
42

如果您试图在整个程序执行过程中维护队列,那么您可能希望使用state monad,这比听起来要简单得多。:)我推荐阅读,这是一本优秀的哈斯凯尔教程,其中包括《州立单子》。

这正是我想要的!谢谢!我会听从你的建议,并查看了解你的Haskell页面。谢谢!:)2注。首先,你有一些多余的理由。无论何时编写
MakeQ(blahblah)
,都要用
MakeQ-blahblah
替换它,以获得更地道的Haskell。其次,
++[x]
效率低下。如果您对效率感兴趣,请查看(或者直接跳到,imho,最佳答案)