免责声明:我是Haskell的新手
我正在尝试基于this设计在haskell中构建一个不透明的多态队列ADT:
module Queue (Queue, empty, isEmpty, frontOf, enqueue, dequeue) where
data Queue a = Queue [a] [a] deriving Show
enqueue :: Queue a -> a -> Queue a
enqueue (Queue xs ys) y = Queue xs (y:ys)
dequeue :: Queue a -> Maybe (Queue a)
dequeue (Queue [] []) = Nothing
dequeue (Queue [] ys) = dequeue (Queue (reverse ys) [])
dequeue (Queue (x:xs) ys) = Just (Queue xs ys)
但是我试图使用newtype
:
module Queue (Queue, empty, isEmpty, frontOf, enqueue, dequeue) where
enqueue :: Queue a -> a -> Queue a
dequeue :: Queue a -> Maybe (Queue a)
newtype Queue a = Qimp ???
...function implementations
所以我的问题是,我应该代替???
。
我试过这个:
newtype Queue a = Qimp ([] [])
但这似乎打破了我职能部门的逻辑,原因可能是受过训练的眼睛显而易见(但对我来说并不明显)。
我似乎陷入困境,因为我的原始实现使用了两个列表来有效地实现队列,但newtype
在构造函数中只需要一个参数。在使用newtype
?
答案 0 :(得分:4)
这个问题似乎是XY问题的一个案例,所以我会尝试解决实际问题并回答你问的问题。
data
类型时,用户可以将其视为列表元组吗?没有。 data
定义创建自己的不同类型(与type
定义不同,后者只创建别名)。
data
是否存在与不透明有关的其他问题?如果导出数据类型的构造函数,则用户可以通过模式匹配使用它们来获取组成队列的列表。为防止这种情况,您不应导出构造函数。
newtype
和data
类型有什么区别? newtype
基本上是data
类型的受限版本,可以更有效地编译。限制是它只能有一个构造函数,并且该构造函数只能有一个参数。
两者之间在懒惰和非终止方面存在语义差异(数据类型可以包含底部, newtype 只能是底部),但对于大多数情况下,这并不重要,只要满足限制,人们只需使用newtype
即可获得更好的性能。
newtype
使类型更不透明吗?不,newtype
的行为与data
类型完全相同(以上述懒惰差异为模)。我对data
类型的不透明性所说的同样适用于newtype
s。
newtype
可以有多个参数吗?不,但它可以有一个参数是一个元组。您可以这样定义:
data Queue a = Queue ([a], [a]) deriving Show
然而,没有理由为什么会这样做。您使用newtype
超过data
类型的原因是性能:您希望安全一级间接。但是,使用元组只是重新引入刚刚保存的间接,因此它的性能完全相同。