Reputation: 24794
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)
Upvotes: 5
Views: 457
Reputation: 116174
For instance,
case undefined of
D d -> "hello"
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 we case
upon.
By contrast, pattern matching on a data
constructor always forces the value we case
upon.
I think this is the only runtime difference between strict data
and newtype
.
There are some static differences, such as some GHC extensions which only affect newtype
, Coercible
, etc., but at runtime the two types are isomorphic (but pattern matching operates differently, as shown above).
Upvotes: 7