A simple question I suspect. I have the simple function definition
makePatientFixture :: [ { name :: String, age :: Int} ];
makePatientFixture = [ { name = "Dave", age = 41}, { name = "Denise", age = 45}, { name = "Cameron", age = 5} ];
I actually want to define a new type called
Patient = { name :: String, age :: Int }
This would mean that I don’t have to repeat the record structure all of the time ({ name :: String, age :: Int }) instead my code would look like:
makePatientFixture :: [ Patient ];
makePatientFixture = [ { name = "Dave", age = 41}, { name = "Denise", age = 45}, { name = "Cameron", age = 5} ];
Is this possible? Does it make sense from a CAL perspective (it may not)?
CAL does not support aliasing (which Haskell does with the ‘type’ keyword), so you can’t just do:
However, you can create a newdata type that incorporates your record:
… however, this is probably not what you need. Records as very handy for moving around bits of structured data and using a structural polymorphism (automatic projection of record subsets). You don’t need to store the data like this though.
Instead, I’d recommend:
The ‘plings’ on the types mean ‘don’t bother storing a lazy thunk here’, e.g. we really want a string and and int even if you apply some complicated expression to the Patient constructor. You can safely omit the plings, but it’s good practice to include them in most cases.
You can now use various forms of case analysis to extract elements from such a Patient value. You’ll see all these in the manual, but here’s a summary:
Overt case analysis, positional match:
Overt case analysis, symbol match:
Lazy extractor
Single case extractor
You can always project a record from this data if you need to.
Remember you can also have multiple constructors for the Patient data type, if there are several kinds of Patient.
For example, perhaps there are in-patients and out-patients. Both of these share some nhs patient records, but have specific fields pertinent to their treatment.
We could represent along the following lines:
This also allows us to look at a very powerful CAL feature that does multiple constructor matching. In this case we match InPatient and OutPatient, projecting only the patientRecords field.
This allows us to write an ‘nhsRecords’ extractor function that we can maintain fairly easily even as the details in the Patient constructors change.
Indeed, unless constructors come and go, or something happens to the “patientRecords” field itself, the this function need never change.