[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