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:
where
GHC will happily erase nested, strict constructors
(!B), and it will make C strict in its first field, optimizing to: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.