... | @@ -49,7 +49,14 @@ The implementation proceeds by adding a new type for unboxed sums and then using |
... | @@ -49,7 +49,14 @@ The implementation proceeds by adding a new type for unboxed sums and then using |
|
We add a new primitive type constructor for the family of unboxed sums:
|
|
We add a new primitive type constructor for the family of unboxed sums:
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
|# t_1 | ... | t_n #|_n
|
|
(# | ... | #)
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
A sum of n "\|"s is a n+1 ary sum. The type constructor can then be used to create a type, like so:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
(# t1 | ... | tn #)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | @@ -62,22 +69,22 @@ There's an construction and elimination form. |
... | @@ -62,22 +69,22 @@ There's an construction and elimination form. |
|
Construction:
|
|
Construction:
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
|# x #|_i_n
|
|
(# ... | x | ... #)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
This creates the *i*th option of an n-ary sum.
|
|
Again we count the bars to decide which alternative of the sum we are creating.
|
|
|
|
|
|
|
|
|
|
Elimination:
|
|
Elimination:
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
case x of
|
|
case x of
|
|
|# x_1 #|_i_n -> ...
|
|
(# ... | x | ... #) -> ...
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
This matches against the *i*th option of an n-ary sum.
|
|
This matches against one of the alternatives of the n-ary sum.
|
|
|
|
|
|
### Core to STG
|
|
### Core to STG
|
|
|
|
|
... | @@ -88,7 +95,7 @@ When going to STG we need to eliminate the unboxed sums. This can be done in [co |
... | @@ -88,7 +95,7 @@ When going to STG we need to eliminate the unboxed sums. This can be done in [co |
|
Given the Core function
|
|
Given the Core function
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
f :: |# t_1 | ... | t_n #| -> ...
|
|
f :: (# t_1 | ... | t_n #) -> ...
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | @@ -97,9 +104,9 @@ we convert it to a call to STG which includes the tag and the maximum number of |
... | @@ -97,9 +104,9 @@ we convert it to a call to STG which includes the tag and the maximum number of |
|
<table><tr><th> Core </th>
|
|
<table><tr><th> Core </th>
|
|
<th> STG
|
|
<th> STG
|
|
</th></tr>
|
|
</th></tr>
|
|
<tr><th>` f :: |# Int#, Bool #|_n -> ... `</th>
|
|
<tr><th>` f :: (# Int# | Bool #) -> ... `</th>
|
|
<th>` f :: Word -> Word -> Pointer -> ... `</th></tr>
|
|
<th>` f :: Word -> Word -> Pointer -> ... `</th></tr>
|
|
<tr><th>` f :: |# Int#, Word# #|_n -> ... `</th>
|
|
<tr><th>` f :: (# Int# | Word# #) -> ... `</th>
|
|
<th>` f :: Word -> Word -> ... `</th></tr></table>
|
|
<th>` f :: Word -> Word -> ... `</th></tr></table>
|
|
|
|
|
|
### Code generation
|
|
### Code generation
|
... | @@ -117,14 +124,14 @@ Given |
... | @@ -117,14 +124,14 @@ Given |
|
|
|
|
|
```wiki
|
|
```wiki
|
|
data T1 a = Some a | None
|
|
data T1 a = Some a | None
|
|
data T2 a = C !(T1 a) -- Cannot UNPACK here
|
|
data T2 a = C {-# UNPACK #-} !(T1 a)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
we generate a "worker" constructor
|
|
we generate a "worker" constructor
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
C |# a, (# #) #|_2
|
|
C (# a | (# #) #)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | @@ -139,8 +146,8 @@ C x |
... | @@ -139,8 +146,8 @@ C x |
|
===> (translates to)
|
|
===> (translates to)
|
|
|
|
|
|
case x of
|
|
case x of
|
|
Some y -> C (|# #|_1_2 y)
|
|
Some y -> C (# y | #)
|
|
None -> C (|# #|_2_2 (# #))
|
|
None -> C (# | (# #) #)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | @@ -155,8 +162,8 @@ case e of |
... | @@ -155,8 +162,8 @@ case e of |
|
case e of
|
|
case e of
|
|
C x' ->
|
|
C x' ->
|
|
let x = case x' of
|
|
let x = case x' of
|
|
|# #|_1_2 y -> Some y
|
|
(# y | #) -> Some y
|
|
|# #|_2_2 _ -> None
|
|
(# | _ #) -> None
|
|
in ... x ...
|
|
in ... x ...
|
|
```
|
|
```
|
|
|
|
|
... | | ... | |