在haskell(模块)中使用队列

时间:2012-01-18 19:15:15

标签: 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 -> 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命令? Imo它也可能是“QQQ”或其他什么。我无法真正测试这是否会导致程序崩溃,因为我不知道如何使用这个模块。

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

1 个答案:

答案 0 :(得分:6)

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

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

队列上的操作已完成,不是通过就地更新现有队列,而是通过队列转换为新队列。例如,如果MakeQa,而Intq,那么Queue Int是另一个enqueue a q Queue Int添加到后面。同样,如果aq,那么Queue Int是另一个没有前元素的dequeue qQueue Int是前面元素本身({{1} }})。

另外,请注意Hugs不再维护;你应该考虑安装基于GHC编译器的Haskell Platform。它包含一个像Hugs一样的“解释器”程序,所以它不仅仅是一个标准的编译器。

以下是如何从交互式提示中使用此队列模块的示例:

front q

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