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 "sub_sines".

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.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to