Extensible Records
Barney Hilken
b.hilken at ntlworld.com
Sun Nov 11 06:34:14 EST 2007
I think this would be a BIG mistake. Whatever system GHC settles on
is almost certain to become part of the Haskell standard, and this
particular system has some deep limitations which could not be got
round without ripping it all out and starting again.
The problem with this (and other "Flex-like") systems is that they
take record extension as the basic operation of record building,
rather than record merging. This means that you can only ever add or
update statically determined fields of a given record.
An important application which is made impossible by this approach is
functions with optional arguments. For example, if you look at the
definition of R (the statistics system) every function has a small
number of mandatory positional arguments, and a very large number of
optional named arguments, which take sensible default values. I want
to be able to write:
> f opts x = let vals = {Opt1 =: default1, ... } |: opts in
> ... vals ... x ...
where '{Opt1 =: default1, ... }' is some fixed record of default
values, and '|:' is record overwrite. The type of f should be
> f :: (a `Subrecord` {Opt1 :=: t1, ...}) => a -> b -> c
where '{Opt1 :=: t1, ...}' is the (fixed) type of '{Opt1 =:
default1, ... }' (and x::b, and c is the type of the result).
The condition 'a `Subrecord` {Opt1 :=: t1, ...}' in the context of
this type means that every field of 'opts :: a' must be a field of
'{Opt1 :=: t1, ...}', but opts can have as few fields as you like.
This is exactly what you want for optional arguments.
This could never be defined in any "Flex-like" system, because these
systems depend on the fact that their record types can be reduced to
a type variable extended by a fixed set of labels. This is a major
restriction to what you can do with them: you can never define
operations like '|:' or '+:' where the second argument does not have
a constant set of fields.
This restriction does not hold for more flexible systems like that
defined by Oleg & co using functional dependencies, or the one I
proposed on this list using type families. Although these systems are
much more flexible than the "scoped labels" system, they would take
LESS work to add to GHC because they have less built-in syntax, and
are almost entirely defined in a library.
I second the call for a records system, but please don't limit us to
something like scoped labels!
Barney.
More information about the Glasgow-haskell-users
mailing list