Whether a variable is demanded is a static property and whether a value is a thunk (all pointers are boxes, some are thunks) is a dynamic property.
Statically, GHC will not try to evaluate the result of otherU
unless you explicitly demand it, but dynamically it will not be a thunk because the otherU
function does not produce thunks. (And GHC does not introduce a new thunk to store the result of otherU
because you do demand the unboxed tuple.)
Lifted values only cause redundant work when (1) thunks are created to store them in, or (2) they are demanded and thus evaluated (which means that it checks whether the value is a thunk and if so runs it). In your program the otherU
function does not create thunks, so (1) is not an issue. It seems you are mostly worried about (2), but that cannot cause an issue if you never demand the value.
If you do demand the y'
then (2) might be an issue, but I’m showing that it produces a case match with a <TagProper>
annotation, which is GHC’s way of telling you that it knows that the value is not a thunk and thus no evaluation needs to happen.