Contents - Cultural View

Contents - Cultural View Contents - Cultural View

culturalview.com
from culturalview.com More from this publisher
14.07.2013 Views

Quark Framework 260 2. Data Declarations In common with other functional languages, CAL provides a way to declare new types using data declarations. Here is an example of declaring a new data type for 'Employee': /** * The Employee data type is an example of a CAL algebraic data type. It * has one data constructor, RegularEmployee. The RegularEmployee data * constructor has 3 fields: name, manager and directReports. * * The firstName and lastName fields have type String. The manager field * has type Maybe Employee. This reflects the fact that an employee may * have one manager or no managers (in the case fo the CEO), and that * manager is also an Employee. directReports has type [Employee] i.e. a * list of 0 or more employees. Note that the manager and directReports * fields have types that recursively refer to the Employee type. In other * words, Employee is a recursive algebraic data type. */ data Employee = RegularEmployee name :: String //the employeeID field is a potential future addition to the //Employee data type. Notice below that case expressions using //field-name based extraction would not need to be updated due //to this change, but case expressions using positional based //extraction would need updating. //employeeID :: Int manager :: (Maybe Employee) directReports :: [Employee] //This deriving clause provides a default instance implementation for //the Show type class for the Employee type. Essentially what this //means is that the Debug.show function will work with Employee //values to display a String representation of the value suitable for //debugging purposes. deriving Show; Note that fields (data constructor arguments) must have names in CAL, as well as their type. The deriving clause makes the data type work with functions defined in certain type classes. Here we ensure that CAL automatically adds the requisite logic to make values of Employee be renderable as strings for the purposes of tracing. Fields can be extracted in a variety of ways: a) Positionally in a case expression: /** * @arg employee * @return the employee's name */ employeeName :: Employee -> String; employeeName employee = case employee of

Quark Framework 261 //illustrates positionally based case expression extraction of the //"name" field of the RegularEmployee data constructor RegularEmployee empname _ _ -> empname; ; b) By field name in a case expression: /** * @arg employee * @return the employee's name */ employeeName :: Employee -> String; employeeName employee = case employee of //illustrates field-name based case expression extraction of the //"name" field of the RegularEmployee data constructor RegularEmployee {name} -> name; ; This method is obviously more stable with respect to changes in data constructor arguments than the positional version c) By a selector expression /** * @arg employee * @return the employee's name */ employeeName :: Employee -> String; employeeName employee = //illustrates data constructor field selection of the directReports //field employee.RegularEmployee.name; Note that CAL allows multiple constructor arguments to be cited in a case extractor, along with multiple constructors to match on (so long as they all have the named arguments). So, the following scenario is possible (assuming the data declaration includes the employeeID field and new constructors for Contractor and Associate): // ...snip... case employee of //illustrates multiple field case expression extraction over multiple //data constructors. Note the local renaming of the employeeID field //to 'id' (RegularEmployee | Contractor | Associate) {name, employeeID = id } -> (name, id); ; // ...snip...

Quark Framework 260<br />

2. Data Declarations<br />

In common with other functional languages, CAL provides a way to declare new types using data declarations. Here<br />

is an example of declaring a new data type for 'Employee':<br />

/**<br />

* The Employee data type is an example of a CAL algebraic data type. It<br />

* has one data constructor, RegularEmployee. The RegularEmployee data<br />

* constructor has 3 fields: name, manager and directReports.<br />

*<br />

* The firstName and lastName fields have type String. The manager field<br />

* has type Maybe Employee. This reflects the fact that an employee may<br />

* have one manager or no managers (in the case fo the CEO), and that<br />

* manager is also an Employee. directReports has type [Employee] i.e. a<br />

* list of 0 or more employees. Note that the manager and directReports<br />

* fields have types that recursively refer to the Employee type. In other<br />

* words, Employee is a recursive algebraic data type.<br />

*/<br />

data Employee =<br />

RegularEmployee<br />

name :: String<br />

//the employeeID field is a potential future addition to the<br />

//Employee data type. Notice below that case expressions using<br />

//field-name based extraction would not need to be updated due<br />

//to this change, but case expressions using positional based<br />

//extraction would need updating.<br />

//employeeID :: Int<br />

manager :: (Maybe Employee)<br />

directReports :: [Employee]<br />

//This deriving clause provides a default instance implementation for<br />

//the Show type class for the Employee type. Essentially what this<br />

//means is that the Debug.show function will work with Employee<br />

//values to display a String representation of the value suitable for<br />

//debugging purposes.<br />

deriving Show;<br />

Note that fields (data constructor arguments) must have names in CAL, as well as their type. The deriving clause<br />

makes the data type work with functions defined in certain type classes. Here we ensure that CAL automatically adds<br />

the requisite logic to make values of Employee be renderable as strings for the purposes of tracing.<br />

Fields can be extracted in a variety of ways:<br />

a) Positionally in a case expression:<br />

/**<br />

* @arg employee<br />

* @return the employee's name<br />

*/<br />

employeeName :: Employee -> String;<br />

employeeName employee =<br />

case employee of

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!