Haskell:带有`newtype`的“多个”参数

zzu*_*zzu -1 haskell

免责声明:我对 Haskell 很陌生

我正在尝试基于设计在 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)
Run Code Online (Sandbox Code Playgroud)

但我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,我用什么来代替???.

我试过这个:

newtype Queue a = Qimp ([] [])
Run Code Online (Sandbox Code Playgroud)

但这似乎打破了我函数中的逻辑,原因对于训练有素的眼睛来说可能是显而易见的(但对我来说并不明显)。

我似乎陷入了困境,因为我的原始实现使用了两个列表来有效地实现一个队列,但newtype在构造函数中只需要一个参数。是否有一种通用/标准的方法来模拟多个构造函数参数newtype

sep*_*p2k 5

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

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

不是。data定义创建了它自己的独特类型(与type定义不同,它只创建一个别名)。

data关于不透明还有其他问题吗?

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

anewtypedata类型有什么区别?

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

有关于懒惰和未结束(数据类型可以在两者之间的语义差别包含底部,一个NEWTYPE只能是底部),但在大多数情况下这件事情不和人简单地使用newtype时的限制得到满足GET更好的性能。

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

不,newtypes 的行为与datatype完全相同(以上面提到的懒惰差异为模)。我所说的关于data类型的不透明性的同样的事情也适用于newtypes。

a 可以newtype有多个参数吗?

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

data Queue a = Queue ([a], [a]) deriving Show
Run Code Online (Sandbox Code Playgroud)

然而,人们几乎没有理由这样做。使用newtypeoverdata类型的原因是性能:您希望保护一级间接。然而,使用元组只会重新引入您刚刚保存的间接,因此它最终完全相同,性能明智。