[Haskell-cafe] Re: Trouble with record syntax and classes

Albert Y. C. Lai trebla at vex.net
Tue Feb 27 15:40:03 EST 2007

Thomas Nelson wrote:
> data ISine = Sine Integer Integer Integer String |
>             MetaSine Integer Integer Integer [ISine]

Having advised you to use different field names for different record 
types last time, I now confuse you by saying you can share field names 
in the different cases inside the same type!

data ISine = Sine {period, offset, threshold :: Int, letter :: String}
            | MetaSine {period, offset, threshold :: Int,
                        sub_sines :: [ISine]}

If the same field name is used in both cases, both fields must be of the 
same type, e.g., "period" is Int throughout.

This only works within the same type, i.e., ISine. Other types still 
cannot have a field named "period".

You no longer need to define a "period" function yourself, since the 
field "period" already does that. "period blah" works whether "blah" is 
a Sine or a MetaSine. "letter blah" works if "blah" is a Sine, aborts if 
"blah" is a MetaSine. (But you kind of want that anyway.) Dually for 

Existing pattern-matching code still works, e.g.,

   act time (Sine p o t l) = ...

still works. (The order of p o t l follows the order of fields in the 
data declaraction.) You can also optionally write

   act time Sine{period=p, offset=o, threshold=t, letter=l} = ...

Either way it is up to you.

Record syntax in Haskell is a bit confusing and restrictive. Both in 
some sense it is also pervertedly convenient.

More information about the Haskell-Cafe mailing list