[Haskell-cafe] records proposals list

David Roundy droundy at abridgegame.org
Sat Nov 19 08:57:09 EST 2005


On Fri, Nov 18, 2005 at 05:42:41PM +0300, Bulat Ziganshin wrote:
>   can anyone write at least the list of record proposals for Haskell?
> or, even better, comment about pros and contras for each proposal?

I'd benefit from just a list of problems that the record proposals want to
solve.

I can list the issues that seem important to me, but I am sure my list
isn't complete.  Also note that some of these goals may be mutually
contradictory, but agreeing on the problems might help in agreeing on the
solutions.

A getter is a way to get a field out of a record, a setter is a way to
update a field in a record.  These may be either pattern-matching syntaxes,
functions or some other odd syntax.

Here's the quick summary, expanded below:

1. The field namespace issue.
2. Multi-constructor getters, ideally as a function.
3. "Safe" getters for multi-constructor data types.
4. Getters for multiple data types with a common field.
5. Setters as functions.
6. Anonymous records.
7. Unordered records.

2. Multi-constructor getters.

1. Field namespace issue:

Field names should not need to be globally unique.  In Haskell 98, they
share the function namespace, and must be unique.  We either need to make
them *not* share the function namespace (which means no getters as
functions), or somehow stick the field labels into classes.

2. Multi-constructor getters, ideally as a function:

An accessor ought to be able to access an identically-named field from
multiple constructors of a given data type:

> data FooBar = Foo { name :: String } | Bar { name :: String }

However we access "name", we should be able to access it from either
constructor easily (as Haskell 98 does, and we'd like to keep this).

3. "Safe" getters for multi-constructor data types.

Getters ought to be either "safe" or explicitly unsafe when only certain
constructors of a data type have a given field (this is my pet peeve):

> data FooBar = Foo { foo :: String } | Bar { bar :: String }

This shouldn't automatically generate a function of type

> foo :: FooBar -> String

which will fail when given a FooBar of the Bar constructor.  We can always
write this function ourselves if we so desire.

4. Getters for multiple data types with a common field.

This basically comes down to deriving a class for each named field, or
something equivalent to it, as far as I can tell.  This also works with the
namespace issue, since if we are going to define getters and setters as
functions, we either need unique field labels or we need one class per
field label--or something equivalent to a class for each field label.

5. Setters as functions.

It would be nice to have a setter function such as (but with perhaps a
better name)

> set_foo :: String -> Foo -> Foo

be automatically derived from

> data Foo = Foo { foo :: String }

in the same way that in Haskell 98 "foo :: Foo -> String" is implicitely
derived.

Note that this opens up issues of safety when you've got multiple
constructors, and questions of how to handle setting of a field that isn't
in a particular datum.

6. Anonymous records.

This idea is from Simon PJ's proposal, which is that we could have
anonymous records which are basically tuples on steroids.  Strikes me as a
good idea, but requires that we address the namespace question, that is,
whether field labels share a namespace with functions.  In Simon's
proposal, they don't.

This is almost a proposal rather than an issue, but I think that it's a
worthwhile idea in its own right.

7. Unordered records.

I would like to have support for unordered records, which couldn't be
matched or constructed by field order, so I could (safely) reorder the
fields in a record.  This is really an orthogonal issue to pretty much
everything else.


Argh.  When I think about records too long I get dizzy.
-- 
David Roundy
http://www.darcs.net


More information about the Haskell-Cafe mailing list