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