在haskell(模块)中使用队列

Sep*_*epp 3 queue haskell module

我有一个关于这个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
Run Code Online (Sandbox Code Playgroud)

我知道队列通常如何工作以及每个操作主要做什么.我的第一个问题是我不知道如何在拥抱中使用这些操作.在创建空队列后如何创建空队列或将元素放入其中?我尝试了几个命令但是所有这些命令都导致了错误消息,即Make([]),emptyQueue [] ......我知道这些命令非常幼稚,但我绝对不熟悉Haskell而且只需要2周或者.

第二个问题是关于"MakeQ"本身.这只是我们操作名称的声明,对吗?或者它是一个静态的Haskell命令?Imo它也可能是"QQQ"或其他什么.我无法真正测试这是否会导致程序崩溃,因为我不知道如何使用这个模块.

即使我的问题看起来有点愚蠢,如果有人可以给我一个解释或提示,我会很高兴...

ehi*_*ird 6

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

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

队列上的操作不是通过就地更新现有队列,而是通过队列转换为新队列来完成的.例如,如果aInt,并且q是a Queue Int,那么enqueue a q另一个Queue Inta添加到后面.类似地,如果q是a Queue Int,那么dequeue q另一个Queue Int没有前元素,并且front q是前元素本身(an Int).

另外,请注意Hugs不再维护; 您应该考虑安装基于GHC编译器的Haskell平台.它包含一个像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
Run Code Online (Sandbox Code Playgroud)

如果你试图在整个程序执行期间维护一个队列,那么你可能想要使用状态monad,这比听起来要糟糕得多.:)我建议阅读Learn You a Haskell,这是一个很好的Haskell教程,涵盖了许多其他东西,状态monad.