So, I didn’t think of this before but ghc can give me an example quite easily so a fairly simple module such as this :
data Test = Test {
fieldA :: Int,
fieldB :: Double,
fieldC :: [Int]
}
data TestMore = TestMore {
fieldD :: Test,
fieldE :: [Test]
}
desugars to this
[1 of 1] Compiling MyModule.Ok ( src/MyModule/Ok.hs, src/MyModule/Ok.o )
==================== Tidy Core ====================
Result size of Tidy Core
= {terms: 148, types: 80, coercions: 0, joins: 0/0}
-- RHS size: {terms: 5, types: 6, coercions: 0, joins: 0/0}
fieldC :: Test -> [Int]
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
fieldC
= \ (ds_dvd :: Test) ->
case ds_dvd of { Test ds1_dve ds2_dvf ds3_dvg -> ds3_dvg }
-- RHS size: {terms: 5, types: 6, coercions: 0, joins: 0/0}
fieldB :: Test -> Double
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
fieldB
= \ (ds_dv9 :: Test) ->
case ds_dv9 of { Test ds1_dva ds2_dvb ds3_dvc -> ds2_dvb }
-- RHS size: {terms: 5, types: 6, coercions: 0, joins: 0/0}
fieldA :: Test -> Int
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
fieldA
= \ (ds_dv5 :: Test) ->
case ds_dv5 of { Test ds1_dv6 ds2_dv7 ds3_dv8 -> ds1_dv6 }
-- RHS size: {terms: 5, types: 5, coercions: 0, joins: 0/0}
fieldE :: TestMore -> [Test]
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
fieldE
= \ (ds_dv2 :: TestMore) ->
case ds_dv2 of { TestMore ds1_dv3 ds2_dv4 -> ds2_dv4 }
-- RHS size: {terms: 5, types: 5, coercions: 0, joins: 0/0}
fieldD :: TestMore -> Test
[GblId[[RecSel]], Arity=1, Unf=OtherCon []]
fieldD
= \ (ds_duZ :: TestMore) ->
case ds_duZ of { TestMore ds1_dv0 ds2_dv1 -> ds1_dv0 }
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule1_ruL :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$trModule1_ruL = "main"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule2_rvv :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$trModule2_rvv = GHC.Types.TrNameS $trModule1_ruL
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$trModule3_rvw :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$trModule3_rvw = "MyModule.Ok"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$trModule4_rvx :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$trModule4_rvx = GHC.Types.TrNameS $trModule3_rvw
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
MyModule.Ok.$trModule :: GHC.Types.Module
[GblId, Unf=OtherCon []]
MyModule.Ok.$trModule
= GHC.Types.Module $trModule2_rvv $trModule4_rvx
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep_rvy :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep_rvy
= GHC.Types.KindRepTyConApp
GHC.Types.$tcDouble (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep1_rvz :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep1_rvz
= GHC.Types.KindRepTyConApp
GHC.Types.$tcInt (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
$krep2_rvA :: [GHC.Types.KindRep]
[GblId, Unf=OtherCon []]
$krep2_rvA
= GHC.Types.:
@GHC.Types.KindRep $krep1_rvz (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep3_rvB :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep3_rvB = GHC.Types.KindRepTyConApp GHC.Types.$tc[] $krep2_rvA
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tcTest1_rvC :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$tcTest1_rvC = "Test"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tcTest2_rvD :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$tcTest2_rvD = GHC.Types.TrNameS $tcTest1_rvC
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
MyModule.Ok.$tcTest :: GHC.Types.TyCon
[GblId, Unf=OtherCon []]
MyModule.Ok.$tcTest
= GHC.Types.TyCon
4959299669405483955##
12816139518062252538##
MyModule.Ok.$trModule
$tcTest2_rvD
0#
GHC.Types.krep$*
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep4_rvE :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep4_rvE
= GHC.Types.KindRepTyConApp
MyModule.Ok.$tcTest (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep5_rvF :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep5_rvF = GHC.Types.KindRepFun $krep3_rvB $krep4_rvE
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep6_rvG :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep6_rvG = GHC.Types.KindRepFun $krep_rvy $krep5_rvF
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep7_rvH :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep7_rvH = GHC.Types.KindRepFun $krep1_rvz $krep6_rvG
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tc'Test1_rvI :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$tc'Test1_rvI = "'Test"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tc'Test2_rvJ :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$tc'Test2_rvJ = GHC.Types.TrNameS $tc'Test1_rvI
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
MyModule.Ok.$tc'Test :: GHC.Types.TyCon
[GblId, Unf=OtherCon []]
MyModule.Ok.$tc'Test
= GHC.Types.TyCon
9856255924558680085##
11575134686824913712##
MyModule.Ok.$trModule
$tc'Test2_rvJ
0#
$krep7_rvH
-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
$krep8_rvK :: [GHC.Types.KindRep]
[GblId, Unf=OtherCon []]
$krep8_rvK
= GHC.Types.:
@GHC.Types.KindRep $krep4_rvE (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep9_rvL :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep9_rvL = GHC.Types.KindRepTyConApp GHC.Types.$tc[] $krep8_rvK
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tcTestMore1_rvM :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$tcTestMore1_rvM = "TestMore"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tcTestMore2_rvN :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$tcTestMore2_rvN = GHC.Types.TrNameS $tcTestMore1_rvM
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
MyModule.Ok.$tcTestMore :: GHC.Types.TyCon
[GblId, Unf=OtherCon []]
MyModule.Ok.$tcTestMore
= GHC.Types.TyCon
8510355829756615054##
17370134490921635344##
MyModule.Ok.$trModule
$tcTestMore2_rvN
0#
GHC.Types.krep$*
-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0}
$krep10_rvO :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep10_rvO
= GHC.Types.KindRepTyConApp
MyModule.Ok.$tcTestMore (GHC.Types.[] @GHC.Types.KindRep)
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep11_rvP :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep11_rvP = GHC.Types.KindRepFun $krep9_rvL $krep10_rvO
-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
$krep12_rvQ :: GHC.Types.KindRep
[GblId, Unf=OtherCon []]
$krep12_rvQ = GHC.Types.KindRepFun $krep4_rvE $krep11_rvP
-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0}
$tc'TestMore1_rvR :: GHC.Prim.Addr#
[GblId, Unf=OtherCon []]
$tc'TestMore1_rvR = "'TestMore"#
-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
$tc'TestMore2_rvS :: GHC.Types.TrName
[GblId, Unf=OtherCon []]
$tc'TestMore2_rvS = GHC.Types.TrNameS $tc'TestMore1_rvR
-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0}
MyModule.Ok.$tc'TestMore :: GHC.Types.TyCon
[GblId, Unf=OtherCon []]
MyModule.Ok.$tc'TestMore
= GHC.Types.TyCon
3029184788634965850##
12315380093137452644##
MyModule.Ok.$trModule
$tc'TestMore2_rvS
0#
$krep12_rvQ
I’ll take a deeper look at this later, but it’s not immediatly obvious to me why the generated core is quadratic in the number of fields from either the explanations in ghc or all the reading from prior sources. That’s my “ultimate” question which hasn’t been answered so far, but I suspect I can find out by myself, eventually.