
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 #)
I don't really understand this explanation. (# T #) being unlifted would mean it's isomorphic to T under the correspondence e<-> (# e #). _|_ = (# _|_ #) : (# T #), so this works.
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. -- Live well, ~wren