Difference between `data` and `newtype` in Haskell and a couple other questions address the general differences between data and newtype. My question is a very specific one. If G is some type, is there any difference between
data T = T !G
and
newtype T = T G?
They appear to have the same strictness properties, and I don't see why the compiler would have any reason to compile them differently, but maybe I'm missing something.
The major difference is in how it's gonna get compiled. All data declarations introduce memory overhead, while newtype don't.
Here's an output of a memory footprint measurement library.
import GHC.DataSize
data A = A !Int
newtype B = B Int
main = do
print =<< (recursiveSize $! A 1)
print =<< (recursiveSize $! B 1)
print =<< (recursiveSize $! 1)
output:
32
16
16
Another difference is mentioned by Shachaf in the first comment.
I'm going to answer a slightly different question: "does newtype add any semantic functionality to Haskell?". I believe the answer is "no".
Suppose we have data Td = Td !G and newtype Tn = Tn G. Then
Td and Tn have exactly the same inhabitants, i.e. the inhabitants of G
g they "contain" is forcedcase but this is only syntactic. There is a direct correspondance between the two versions.The following table explains how a newtype Tn can be replaced by a data Td in a case statement. There's also a translation back the other way.
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 ...
So semantically speaking I believe Haskell could have avoided adding newtype. Syntactically speaking newtype maybe makes case statements a less awkward, that's all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With