[Haskell] (small) records proposal for Haskell '06

David Roundy droundy at abridgegame.org
Mon Jan 2 08:43:56 EST 2006

Hi all,

I'd like to humbly submit a conservative proposal for changes to the
records mechanism for Haskell '06.  The plan for Haskell '06 (to the extent
that there is one) is to make it a conservative modification of Haskell
98, which is a good idea.  As such, I don't think features should be added
to the language that haven't been both implemented and tested, and the
problem with the whole records problem is that pretty much every proposed
improvement is *not* backwards-compatible with Haskell 98, and therefore
hasn't been either implemented or tried out.

My idea is to make a small change, which will also not be
backwards-compatible with Haskell 98, but will *almost* be, and will be
hopefully forward-compatible with most complete solutions.  At a minimum,
the proposed change will allow the prototyping of real solutions as a
non-invasive preprocessor a la DrIFT.

My proposal is simply to remove the automatic declaration of accessor
functions.  In Haskell 98,

data FooBar = Foo { foo :: Int } | FooBar = { foo :: Int, bar :: Int }

desugars to something like

data FooBar = Foo Int | FooBar Int Int

foo :: FooBar -> Int
foo (Foo f) = f
foo (FooBar f _) = f
bar :: FooBar -> Int
bar (Foo _) = error "bad Foo"
bar (FooBar _ b) = b

plus additional sugar for constructors and pattern matching.  I would leave
the sugar for constructors and pattern matching in place, but remove the
automatic declaration of functions "foo" and "bar".

This change "solves" the problem that different records in a single
namespace cannot share field names in a simple manner.  In order to allow
the writing of records code with is both valid Haskell 98 and valid Haskell
'06, I'd suggest a pragma that causes the Haskell '06 compiler to generate
the accessor functions.  It's a bit ugly, but seems best to me.  An
alternative would be a standard TH function to do the same, but I don't
know if TH is going to be included in Haskell '06.

This change may look like a step backwards (which it is), but I think that
it would allow significant steps forward.

One open question (in my mind) would be whether we'd allow

data Foo = FooInt { foo :: Int } | FooChar { foo :: Char }

In the "new" system, there's no reason this need be illegal.
David Roundy

More information about the Haskell mailing list