# Type Unions

## Enumerated type unions

Last time, we saw “type declarations:” `type` name `=` type-expr

The simplest case that does introduces a new type and values is an enumerated union:
`type` `name` `=` `Value1` `|` `Value2` `| ... |` `Value𝓀`

For example:

``type size = Tall | Grande | Venti``

Introduces the new type `size`, and three values that only belong to the type size: `Tall`, `Grande`, `Venti`.

# Disjoint Unions

We can also use `type` to declare a disjoint union type:

``````type number = Int of int
| Real of float
| Complex of float*float``````

This declaration introduces new value constructors: `Int`, `Real`, and `Complex` construct new values of type `number`.

`# let x = Int 2 ;;`

`val x : number = Int 2`

`# let y = Real 2.0 ;;`

`val y : number = Real 2.0`

`# let z = Complex (1.414, 1.414) ;;`

`val z : number = Complex (1.414, 1.414)`

`# let zeta = Complex 0.0 ;;`

Value constructors are not functions but follow type constraints.

## Functions on disjoint unions

Computing with disjoint unions works similarly to lists and product types:

``````let abs x = match x with
| Int n -> float_of_int (abs n)
| Real r -> abs_float r
| Complex (r,i) -> sqrt(r*.r +. i*.i)``````
``````let rec sum_ints = function
| [] -> 0
| (Int n)::t -> n + sum_ints t
| (Real _)::t | (Complex _)::t -> sum_ints t``````

## Examples

Define `real_part`, `imag_part : number -> float`

type `hostinfo` that is either a 4-tuple of `int`s or a domain name (`string`).

`find_domains : hostinfo list -> hostinfo list`

`class_b_subnet : hostinfo -> int*int`

## Polymorphic value constructors

Disjoint unions can also be parametric: e.g. what should `imag_part` and `class_b_subnet` do:

``````let imag_part = function
| Complex (_,i) -> i
| Real _ | Int _ -> (* ?? *)``````

One possibility: the predefined `option` type:

`type 'a option = None | Some of 'a`

``````# let imag_part = function
| Complex (_,i) -> Some i
| Real _ | Int _ -> None ;;``````

`val imag_part : number -> float option`

## Examples

``class_b_subnet : hostinfo -> (int*int) option``
``````hd_opt : 'a list -> 'a option
tl_opt : 'a list -> 'a list option``````
``list_max_opt : 'a list -> 'a option``

# `cs2041.org`

// reveal.js plugins