
This message is to air a possible change in the way GHC handles constructors. Before I make the change I want to check that it isn't going to mess anyone up. There's some background in http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/the-beast/data-types.h tml Consider the following data T = MkT !(Int,Int) f x y = MkT (x,y) g (MkT (x,y)) = x If you compile this with -funbox-strict-fields, GHC will unbox the strict pair, to give effectively this data T = MkT Int Int f x y = MkT x y g t = case t of MkT x y -> x Rather than find all the applications of MkT, it actually *defines* MkT like this MkT p = case p of (x,y) -> $wMkT x y where $wMkT is the "real" constructor. So the "real" data type is data T = $wMkT Int Int and MkT is just a "wrapper function". However in Core-language case expressions we still print 'MkT': g t = case t of MkT a b -> ... even though the "real" constructor is $wMkT. (On the face of it, MkT a b isn't even well typed.) This is a bit of a mess, especially when we print External Core. Then we get data T = MkT Int Int MkT p = case p of (x,y) -> $wMkT x y f x y = $wMkT x y g t = case t of MkT x y -> x Strange! MkT looks like the constructor for T, but is also given a definition; and $wMkT doesn't seem to be defined at all. This gives rise to difficulties when reading External Core back in. We could make this more consistent in two ways. Alternative (A): One way would be to make it clearer that $wMkT was the real constructor: data T = $wMkT Int Int MkT p = case p of (x,y) -> $wMkT x y f x y = $wMkT x y g t = case t of $wMkT x y -> x This is consistent, but it makes External Core a bit funny. (The real constructors are always $w things.) Alternative (B): The other alternative would be to make the original Haskell constructors into the $w things: data T = MkT Int Int $wMkT p = case p of (x,y) -> MkT x y f x y = MkT x y g t = case t of MkT x y -> x This makes Core (and External Core) nice and consistent, with traditional upper-case constructors, but MkT now has a different type than in the original program. We'd need to take care when printing type errors etc that we didn't print $wMkT when the programmer expected MkT. (That isn't too hard.) Personally, I'm inclined to alternative (B). Do any of you have an opinion? Especially folk using External Core? Simon