
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

On Wed, Dec 11, 2002 at 11:40:39AM -0000, Simon Peyton-Jones wrote:
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.)
Speaking as a common user who hasn't used External Core for anything, this one looks much more attractive to me. Consistency and predictable typing is important, and it's ok for things to look funny because, after all, funny things _are_ going on when special optimizations are applied. Lauri Alanko la@iki.fi
participants (2)
-
Lauri Alanko
-
Simon Peyton-Jones