Records (was Re: [Haskell] Improvements to GHC)
David Roundy
droundy at abridgegame.org
Wed Nov 23 08:22:47 EST 2005
On Tue, Nov 22, 2005 at 02:32:47PM +0000, Rob Ennals wrote:
> Since discussion has returned to records, it might be useful for me to
> post a link to a proposal that I knocked up a while back when this
> topic came up a few years ago:
>
> http://www.cambridge.intel-research.net/~rennals/records.pdf
Looks pretty nice.
> To go through Dave's issues:
>
> 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. This is a stupid
example (thus the type names), but I think there are real cases where you'd
like to create constructors like this.
> 2. Multi-constructor getters: solved by desugaring to functions
> 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
which die when given bad input (e.g. calling (foo $ Bar "bar")). I'd
rather in this case either not have these functions generated (and require
that I use pattern matching) or have them have type
foo :: FooBar -> Maybe String
bar :: FooBar -> Maybe String
I just don't like bottom. Perhaps it wouldn't be so bad if we got decent
error messages, but when you call (foo $ Bar "bar") you get no hint as to
where the bug actually is.
> 7. Unordered records: yep (if I understand the problem correctly)
I don't think you understood correctly. What I'd like (and this is another
one of those David-specific issues--I've never heard anyone else complain
about this) is to be able to create a data type that has no order. If I
write
data FooBar = FooBar { foo, bar :: String }
I can construct this (either with Haskell 98 or with your proposal, as I
understand it) with either
fb = FooBar { foo = "a", bar = "b" }
or with
fb = FooBar "a" "b"
I'd prefer to at least optionally be able to make the second syntax fail to
compile--which is what I mean by an unordered record. The same goes for
pattern matching. This feature is orthogonal to almost all the other
record issues, and really a compiler warning would probably be enough to
satisfy me, although I'd prefer to have this in the language.
The point (in case I've been unclear again) is that I'd like to be able to
later change the definition to
data FooBar = FooBar { foo, bar :: String }
without the possibility of breaking the code. This is a silly example, and
noone would actually make this change, simply because it would be too hard
to go through the code and verify that all the patterns have been swapped
(and didn't get swapped twice).
It's something that one could implement with code policy, but on the other
hand, you could in principle say the same thing about static typing.
--
David Roundy
http://www.darcs.net
More information about the Haskell
mailing list