# 1.1 Unions and Matches

The dual concept to structures is unions. A structure has "each of" logic whereas a union has "one of logic". Each-of logic demands treating each of the components in sequence whereas one-of logic demand selecting one of the components.

Unions therefore represent alternatives. We use pattern matching with
the `match`

construction to discover which alternative is encoded
and handle it in a typesafe manner. A `match`

is an advanced form
of a `switch`

: `union`

s are an advanced form of an `enum`

eration.

union boolean = | True | False ; var b:boolean = True; proc f(b:boolean) { match b with | #True => println "True"; | #False => println "False"; endmatch; } println$ match b with | #True => "True" | #False => "False" endmatch;

This code demonstrates a simple union of two cases: `True`

and `False`

and shows a procedural `match`

whose case handlers are `println`

statements, and a function `match`

whose handlers are expressions.

A more sophisticated example:

union Z = | Cart of double * double // cartesian complex x+iy | Polar of double * double // polar complex re^(i\theta) ; fun str (z:Z) => match z with | Cart (x,y) => str x + "+"+str y+"i" | Polar (r,theta) => str r + "e^"+str theta+"i" endmatch ;

The identifiers `Cart`

and `Polar`

here are called *type constructors*
or just plain constructors, note here the arguments of the constructors
are both the same: a pair of `double`

.

The question mark {?} here is used to introduce a parameter to represent the argument.

Unions are the way to unify heterogenous data types. If you're
from an OO background you may think subclassing should be used
for this. Unlearn this error. It is *utterly* wrong.

Subclassing is a way to represent a subtype, that is, a type with a subset of values of another type: for example the set of triangular matrices is a subtype of all matrices.

Similarly, composition using tuple or structs is the way to add more data to a type. Not inheritance. Unlearn that mistake too!

The match construction is very powerful. It can be used to match tuples and records too:

fun fst (a:int * long) => match a with | x,_ => x endmatch ; fun xaxis (a:(x:double, y:double))=> match a with | (x=xval) => xval endmatch ; println$ fst (41,99l); println$ xaxis (x=1.2,y=2.2);

Here the `_`

is a wildcard that matches anything.

You can also match against literals and ranges of integers floats and strings:

fun matcher (x:int) => match x with | 1 => "one" | 2..10 => "two to ten" | _ => "other" endmatch ;

Of course, matches are general patterns and can be combined, we've already seen that in the first example which combines are match against constructors and tuples.

## 1.1.1 Enumerations

Felix has C++ style `enum`

s.

### 1.1.1.1 Linear enumeration

enum colour {red, green, blue}; instance Str[colour] { fun str: colour -> string = | #red => "red" | #blue => "blue" | #green => "green" ; } println$ red;

This is a shorthand for a union, where the enumeration tags are type constuctors.

Note also in the above example the shorthand version of a function which consists solely of a match.

### 1.1.1.2 Flags

Here's an example with user specified constructor indicies:

enum flags {b1=1,b2=2,b3=4}; println$ caseno b3; // Use C to model flag like operations type flagset = "int"; ctor flagset: flags = "$1"; fun \(\vee\) :flags * flags -> flagset = "$1|$2"; fun \(\vee\) :flags * flagset -> flagset = "$1|$2"; fun \(\vee\) :flagset * flags -> flagset = "$1|$2"; fun \(\cup\) :flagset * flagset -> flagset = "$1|$2"; fun \(\in\) : flags * flagset -> bool = "($1&$2)!=0"; fun ==: flagset * flagset -> bool = "$1==$2"; fun !=: flagset * flagset -> bool = "$1!=$2"; fun \(\subseteq\) : flagset * flagset -> bool = "($1&~$2)==0"; fun \(\subset\) (x:flagset,y:flagset)=> x \(\subseteq\) y and not x == y; fun \(\supset\) (x:flagset,y:flagset)=> not x \(\subseteq\) y; fun \(\supseteq\) (x:flagset,y:flagset)=> not x \(\subset\) y; var x = b1 \(\vee\) b2; // infix operator \| is function bor! println$ b1 \(\in\) x; // true: infix operator in is function mem! println$ b2 \(\in\) x; // true println$ b3 \(\in\) x; // false println$ b1.flagset \(\subset\) x; // true println$ x \(\subset\) b1.flagset; // false

You can find the index
of any constructor as an `int`

with the `caseno`

operator.
In the example note that although the constructor with index
0 and 3 is not named, it is still a value of the type.

You cannot directly perform mathematical or bitwise operations
on constructors, not even enumeration constants. Note that that includes
comparison for equality! Use the `caseno`

operator to get around this,
or bind into C as shown in the example.