
On January 10, 2012 12:18:13 wren ng thornton wrote:
On 1/10/12 11:18 AM, Dan Doel wrote:
On Tue, Jan 10, 2012 at 11:14 AM, Dan Doel
wrote: On Tue, Jan 10, 2012 at 5:01 AM, Simon Marlow
wrote: On 09/01/2012 04:46, wren ng thornton wrote:
Shouldn't (# T #) be identical to T?
No, because (# T #) is unlifted, whereas T is lifted. In operational terms, a function that returns (# T #) does not evaluate the T before returning it, but a function returning T does. This is used in GHC for example to fetch a
value from an array without evaluating it, for example: indexArray :: Array# e -> Int# -> (# e #)
With my revised understanding we have the following family of types:
T pointed, lifted, lazy (# T #) pointed?, unlifted, lazy !T unpointed, lifted, eager {-#UNPACK#-}!T unpointed, unlifted, eager
where the two !T types are only specified in ADTs and through strictness analysis. Though this doesn't explain the difference in operational behavior for their use as return types.
IIRC, don't functions in the STG machine evaluate their returned values to WHNF as the very fact that a (lazy) function has comes under valuation implies that its result is to be deconstructed (in a case statement)? An unboxed tuple would already be in WHNF, so this would not be the case (it would be wrong to evaluate the arguments as the case statement forcing the valuation may not do more than deconstruct the unboxed tupple). Cheers! -Tyson