Unit unboxed tuples

Simon Marlow marlowsd at gmail.com
Wed Jan 11 14:41:04 CET 2012


On 10/01/2012 16:18, Dan Doel wrote:
> Copying the list, sorry. I have a lot of trouble replying correctly
> with gmail's interface for some reason. :)
>
> On Tue, Jan 10, 2012 at 11:14 AM, Dan Doel<dan.doel at gmail.com>  wrote:
>> On Tue, Jan 10, 2012 at 5:01 AM, Simon Marlow<marlowsd at gmail.com>  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.
>
> Does the difference have to do with unboxed types? For instance:
>
>     foo :: () ->  Int#
>     foo _ = foo ()
>     bar :: () ->  (# Int# #)
>     bar _ = (# foo () #)
>
>     baz = case bar () of _ ->  5  -- 5
>     quux = case foo () of _ ->  5 -- non-termination
>
> Because in that case, either (# Int# #) is lifted, or the Int# is
> effectively lifted when inside the unboxed tuple. The latter is a bit
> of an oddity.

Unboxed types cannot be lifted, so in fact bar compiles to this:

   bar = \_ -> case foo () of x -> (# x #)

and both baz and quux diverge.

It might help to understand (# T #) by translating it to (# T, () #). 
There's really no difference.

Cheers,
	Simon



More information about the Glasgow-haskell-users mailing list