免责声明:我对 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?
这个问题似乎是 XY 问题的一个案例,所以我将尝试解决实际问题并回答您提出的问题。
data使用一个带有两个列表的构造函数定义类型时,用户是否可以将其视为列表元组?不是。data定义创建了它自己的独特类型(与type定义不同,它只创建一个别名)。
data关于不透明还有其他问题吗?如果导出数据类型的构造函数,用户可以通过模式匹配使用它们来获取构成队列的列表。为了防止这种情况,您不应该导出您的构造函数。
newtype和data类型有什么区别?Anewtype基本上是一种data可以更有效编译的类型的受限版本。限制是它只能有一个构造函数,并且那个构造函数只能有一个参数。
有关于懒惰和未结束(数据类型可以在两者之间的语义差别包含底部,一个NEWTYPE只能是底部),但在大多数情况下这件事情不和人简单地使用newtype时的限制得到满足GET更好的性能。
newtype会使类型更不透明吗?不,newtypes 的行为与datatype完全相同(以上面提到的懒惰差异为模)。我所说的关于data类型的不透明性的同样的事情也适用于newtypes。
newtype有多个参数吗?不,但它可以有一个元组参数。你可以这样定义它:
data Queue a = Queue ([a], [a]) deriving Show
Run Code Online (Sandbox Code Playgroud)
然而,人们几乎没有理由这样做。使用newtypeoverdata类型的原因是性能:您希望保护一级间接。然而,使用元组只会重新引入您刚刚保存的间接,因此它最终完全相同,性能明智。