
#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