Haskell:“newtype”的“多个”参数

时间:2017-03-15 19:38:08

标签: haskell

免责声明:我是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

时,是否有一种通用/标准方法来模拟多个构造函数参数

1 个答案:

答案 0 :(得分:4)

这个问题似乎是XY问题的一个案例,所以我会尝试解决实际问题并回答你问的问题。

当我使用一个带有两个列表的构造函数定义data类型时,用户可以将其视为列表元组吗?

没有。 data定义创建自己的不同类型(与type定义不同,后者只创建别名)。

data是否存在与不透明有关的其他问题?

如果导出数据类型的构造函数,则用户可以通过模式匹配使用它们来获取组成队列的列表。为防止这种情况,您不应导出构造函数。

newtypedata类型有什么区别?

newtype基本上是data类型的受限版本,可以更有效地编译。限制是它只能有一个构造函数,并且该构造函数只能有一个参数。

两者之间在懒惰和非终止方面存在语义差异(数据类型可以包含底部, newtype 只能是底部),但对于大多数情况下,这并不重要,只要满足限制,人们只需使用newtype即可获得更好的性能。

使用newtype使类型更不透明吗?

不,newtype的行为与data类型完全相同(以上述懒惰差异为模)。我对data类型的不透明性所说的同样适用于newtype s。

newtype可以有多个参数吗?

不,但它可以有一个参数是一个元组。您可以这样定义:

data Queue a = Queue ([a], [a]) deriving Show

然而,没有理由为什么会这样做。您使用newtype超过data类型的原因是性能:您希望安全一级间接。但是,使用元组只是重新引入刚刚保存的间接,因此它的性能完全相同。