Difference between `data` and `newtype` in Haskell以及其他几个问题解决了数据和newtype之间的一般差异。我的问题非常具体。如果G
是某种类型,那么
data T = T !G
和
newtype T = T G
?
它们似乎具有相同的严格属性,我不明白为什么编译器有任何理由以不同的方式编译它们,但也许我错过了一些东西。
答案 0 :(得分:3)
主要区别在于它将如何编译。所有data
声明introduce memory overhead,而newtype
不声明。
这是内存占用测量库的输出。
import GHC.DataSize
data A = A !Int
newtype B = B Int
main = do
print =<< (recursiveSize $! A 1)
print =<< (recursiveSize $! B 1)
print =<< (recursiveSize $! 1)
输出:
32
16
16
Shachaf在第一条评论中提到了另一个不同之处。
答案 1 :(得分:2)
我将回答一个稍微不同的问题:“newtype
是否将任何语义功能添加到Haskell?”。我相信答案是“不”。
假设我们有data Td = Td !G
和newtype Tn = Tn G
。然后
Td
和Tn
拥有完全相同的居民,即G
g
他们“包含”被迫case
的互动方式不同,但这只是句法。两个版本之间存在直接对应关系。下表说明newtype
Tn
如何在data
声明中替换为Td
case
。另一种方式也有翻译。
Tn Td
case tn of _ -> ... case td of _ -> ...
case tn of Tn _ -> ...
case tn of Tn x -> ... x ... let x1 = case tn of Td x -> x in ... x1 ...
case tn of x -> ... x ... case td of x -> ... x ...
case tn of Tn x -> x `seq` ... case td of Td _ -> ...
case tn of Tn x -> x `seq` ... x ... case td of Td x -> ... x ...
从语义上讲,我相信Haskell可以避免添加newtype
。从句法上讲,newtype可能会使case
语句变得不那么尴尬,就是这样。