labelled fields

George Russell ger@tzi.de
Wed, 04 Jun 2003 15:55:48 +0200


Steffen wrote
 > I need something like
 >
 > data Type = TCon String {lmtc::Maybe String} ...
 >
 > but this does not seem to be possible. Instead
 > I have to waste identifiers:
 >
 > data Type = TCon {senseless::String,lmtc::Maybe String} ...
 >
 > Why? Are there any formal reasons against the
 > above declaration?

Clearly it's arguable, since SML allows general record types.
My SML syntax is rusty but I think you could write:
 > datatype ty = ty string {lmtc : string option}
or indeed use {lmtc : string option} just like a type.

I don't think haskell@haskell.org is suitable for lengthy
discussions of the merits of SML versus Haskell or vice-versa,
so I will state my view and leave it at that:
(1) the Haskell approach costs you slightly more typing.
(2) on the other hand the error messages are slightly better,
since if you type TCon {sensless = "foo"} the compiler should
spot immediately that "sensless" has no place in a TCon, while
in ML the compiler will have to say something like "Expecting a
{senseless :: String}, found a {sensless :: String}", which leaves
you to work out what it is about the context that requires a
"{senseless :: String}"
(3) the Haskell approach allows several constructors to have the
same field name, for example

 > data Ty1 =
 >       TCon1 {lmtc :: Maybe String}
 >    |  TCon2 {lmtc :: Maybe String, extraField :: String}

and you then have a function lmtc :: Ty1 -> Maybe String which works
for all constructors having the lmtc field.
(4) Haskell will fill in undefined fields, with values that give
error messages if you try to look at them.

Which you prefer is entirely up to you.  None of the above points
are terribly important.  I personally prefer the Haskell approach,
but not by much.