免责声明:我对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)但我正在尝试使用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时是否有一种通用/标准的方法来模拟多个构造函数参数
发布于 2017-03-15 23:11:07
这个问题似乎是XY问题的一个例子,所以我将尝试解决实际问题,并回答您提出的问题。
当我用一个包含两个列表的构造函数定义一个data类型时,用户能把它当作列表的一个元组吗?
不是的。data定义创建自己的不同类型(与type定义不同,后者只创建别名)。
与data有关的不透明还有什么其他问题吗?
如果导出数据类型的构造函数,用户可以通过模式匹配使用它们来获取组成队列的列表。为了防止这种情况,不应该导出构造函数。
newtype和data类型有什么区别?
newtype基本上是data类型的受限版本,可以更有效地编译。这些限制是,它只能有一个构造函数,而构造函数只能有一个参数。
这两种类型在惰性和非终止性方面存在语义差异(数据类型可以包含底部,新类型只能包含底部),但在大多数情况下这并不重要,只要满足限制条件,人们就会使用newtype来获得更好的性能。
使用newtype是否会使类型更不透明?
不,newtype的行为与data类型完全相同(模块化上面提到的惰性差异)。关于data类型的不透明性,我说的同样的东西也适用于newtype的。
一个newtype可以有多个参数吗?
不是,但它可以有一个参数是元组。你可以这样定义它:
data Queue a = Queue ([a], [a]) deriving Show然而,没有什么理由会这样做。在newtype类型上使用data的原因是性能:您希望保护一个级别的间接。然而,使用元组只是重新引入了您刚刚保存的间接方向,所以它的结果与刚才保存的完全相同,从性能上讲。
https://stackoverflow.com/questions/42819189
复制相似问题