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!


More information about the Glasgow-haskell-users mailing list