haskell(模块)中队列的使用
我有一个关于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
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,最佳答案)