[GHC] #14826: Flatten data types extending other data types in STG
GHC
ghc-devs at haskell.org
Wed Feb 21 09:38:19 UTC 2018
#14826: Flatten data types extending other data types in STG
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner: (none)
Type: feature request | Status: new
Priority: low | Milestone:
Component: Compiler | Version: 8.5
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Interesting.
Consider what happens today with the Haskell source
{{{
data T = MkT {-# UNPACK #-} !Int Bool
f (MkT n b) = MkT (n+1) b
}}}
We get the following Core
{{{
data T = MkT Int# Bool
$WMkT :: Int -> Bool -> T
$WMkT n = case n of I# n# -> MkT n# b
f x = case x of
MkT n# b -> let n = I# n#
in $WMkT (n+1) b
}}}
That is
* The "real" Core data constructor `MkT` has an `Int#` field.
* The wrapper `$WMkT` is an ordinary function that unboxes the field and
calls the "real" data constructor
* Pattern matching is desugared to rebox the field
You could do the same thing here. With your example source
{{{
data Foo = A Int | B Bool | C
data Result = Ok !Foo | NotOK Error
f :: Result -> Int
f (Ok x) = wimwam x True x
f (NotOk _) = 0
}}}
you might desugar to
{{{
data Result = Ok_A Int | OK_B Bool | OK_C C | NotOK Error
f r = join j x = wimwam x True x
in case r of
OK_A n -> jump j (A n)
OK_B b -> jump j (B b)
OK_C -> jump j C
NOtOK _ -> 0
}}}
Note that I am NOT re-using the data constructor for `Foo` (which would be
tricky and confusing). I'm simply generating new ones.
-----------------
I think this would be do-able. It uses basically the same concepts as
now, but generalises a bit. I wonder if we could leverage pattern
synonyms rather than have more built-in stuff.
--------------
A concern: it could blow up
{{{
data T = MkT !(Maybe Int) !(Maybe Int)
}}}
Do we generate four constructors? In general a multiplicative number?
You suggest just one field, but it'd be a shame of your perf went down the
tubes because you added an innocuous field.
And actually two or more is fine, provide only one expands to a
multiplicity:
{{{
data T = MkT !Char !(Maybe Int) Bool
}}}
is absolutely ok, desugaring to
{{{
data T = MkT_Just Char# Int Bool
| MkT_Nothing Char# Bool
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14826#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list