How does this code
data D = D { _d :: ![P] } -- Note the strictness annotation!
Compare to this
newtype D = D { _d :: [P] }
An answer to a related question says:
the main difference between data and newtype is that with data is that data constructors are lazy while newtype is strict
How does this difference work when the data
version has a strictness annotation?
(the question is based on real code the I've stumbled on)
For instance,
will error out for
data
types (strict or not strict), but will evaluate to"hello"
for newtypes.This is because, at runtime, applying a
newtype
constructor, or pattern matching on it corresponds to no operation. Not even forcing the value wecase
upon.By contrast, pattern matching on a
data
constructor always forces the value wecase
upon.I think this is the only runtime difference between strict
data
andnewtype
. There are some static differences, such as some GHC extensions which only affectnewtype
,Coercible
, etc., but at runtime the two types are isomorphic (but pattern matching operates differently, as shown above).