My understanding is that an Int value is a pointer to a thunk (double indirection) and an unboxed Int# is just a pointer to a 32/64 bit int. Is that correct? How does the pointer encode the fact that it's referring to an unboxed value?
The Haskell standard states that an Int is "A fixed-precision integer type with at least the range [-2^29 .. 2^29-1]". Is there some optimization in GHC where those extra bits are used to eliminate the indirections?