Records (was Re: [Haskell] Improvements to GHC)

Rob Ennals rob.ennals at
Sun Nov 27 15:47:54 EST 2005

On 11/23/05, David Roundy <droundy at> wrote:
> On Tue, Nov 22, 2005 at 02:32:47PM +0000, Rob Ennals wrote:

> > 1. Field namespaces: solved by using type classes
> But these classes are required to be manually specified, right? This avoids
> the problem of proliferation of typeclasses if one had one class per field,
> but does mean that coordination is necesary in order to avoid namespace
> clashes.
> As far as I can tell, this means that we'd have issues with
> data StupidDouble = StupidDouble { value :: Double }
> data StupidInt = StupidInt { value :: Int }
> unless we use multiparameter typeclasses or something.

You are indeed right.

My thinking was that fields should be thought of in much the same way
as functions. If two same-named fields are supposed to be used the
same way, then one should declare a type class, and if they are
supposed to be distinct, then one should use module namespaces.

As regards multiparameter typeclasses - I think that they should work
quite well with this proposal.


class HasVal a b where
    value :: a -> b

instance HasVal StupidDouble Double
instance HasVal StupidDouble Int

> > 3. "Safe" getters for multi-constructor data types: ditto
> I think either you misunderstood my meaning by "safe", or I misunderstood
> your paper.  I meant that if I write
> data FooBar = Foo { foo :: String } | Bar { bar :: String }
> there shouldn't be accessors of type
> foo :: FooBar -> String
> bar :: FooBar -> String

I did indeed misunderstand what you meant by "safe". Bottom is indeed
a nasty thing.

Perhaps such definitions should generate a warning? (banning them
outright would cause compatability issues)

> > 7. Unordered records: yep (if I understand the problem correctly)
> I don't think you understood correctly.

I was thinking along the same lines as Wolfgang : don't export the
internal representation of the type, but do expose the field
manipulator functions.

This needn't prevent the use of pattern matching, provided the
desugaring of patterns is consistent with the rest of the system.

E.g. I was assuming that

case e of { x = 3, y = 4} -> ...

would desugar to

case e of _ | x z = 3 && y z = 4 -> ...

Note that this pattern matching syntax will continue to work, even if
'x' and 'y' are reimplemented as normal functions, rather than fields.

Hope this all makes sense.


More information about the Haskell mailing list