I often gather multiple values in tuples, since I consider tuples to be the natural type for this. However, tuples are not strict. So consider
data A
data B =
B !A
data C =
C !(B, B)
data D =
D !B !B
With -funbox-strict-fields
and optimization, UNPACKs are nested. Will the tuple in C
be unpacked into C A A
as with D
, or just C B B
? Here is a reference in GHC-doc: 7.16. Pragmas.
(are non-empty tuples types? type-constructors?)
Consider:
data B = B !Int
data C = C !(B, B)
data D = D !B !B
b0 = B 7
b1 = B 4
c = C (b0, b1)
d = D b0 b1
where
data (,) a b = (a,b)
GHC will happily erase nested, strict constructors (!B)
, and it will make C strict in its first field, optimizing to:
b0 = B 7
b1 = B 4
c = C b0 b1
d = D 7 4
However, importantly, the fields of (,)
itself are not strict -- so GHC can't unpack them. Furthermore, they're polymorphic, so it can't unpack them even if they are strict.
A work around for the first part is to use strict tuples. The workaround for the second part is to use self-specializing tuples (e.g. type families that specialize tuples).
Note that using tuples for syntax in this style incurs overhead -- they introduce a level of indirection that must be optimized away. As such, it is somewhat unidiomatic.
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