The F# tutorial includes the following snippet:
/// A record for a person's first and last name
type Person = {
First : string
Last : string
}
/// define a discriminated union of 3 different kinds of employees
type Employee =
| Engineer of Person
| Manager of Person * list<Employee> // manager has list of reports
| Executive of Person * list<Employee> * Employee // executive also has an assistant
The fact that Manager and Executive are described as tuples offends my sensibilities (I'm easily offended). It strikes me as not terribly expressive. I tried to modify them as follows:
/// define a discriminated union of 3 different kinds of employees
type Employee =
| Engineer of Person
| Manager of { Name: Person; Reports: Employee list } // manager has list of reports
| Executive of { Name: Person; Reports: Employee list; Assistant: Employee} // executive also has an assistant
Sadly, the definitions of Manager and Executive now give an error: "This construct is deprecated; consider using a separate record type instead." Ok, seems fair, let's call it ManagerType. But wait ... ManagerType refers to Employee (for the Reports part), and Employee refers to ManagerType (for the Manager option).
Is there a solution here? Is it not possible for two data structures to be defined in terms of each other?
A discriminated union is a union data structure that holds various objects, with one of the objects identified directly by a discriminant. The discriminant is the first item to be serialized or deserialized. A discriminated union includes both a discriminant and a component.
Discriminated unions are useful for heterogeneous data; data that can have special cases, including valid and error cases; data that varies in type from one instance to another; and as an alternative for small object hierarchies.
You can define mutually dependent types using and
:
type Employee =
| Engineer of Person
| Manager of Manager // manager has list of reports
| Executive of Executive
and Manager = { Name: Person; Reports: Employee list }
and Executive = { Name: Person; Reports: Employee list; Assistant: Employee }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With