So far we’ve seen:
Simple types:
Function types:
Product types:
List types:
int
, float
, string
, char
, bool
, unit
τ1 -> τ2
'a * 'b
, 'a * 'b * 'c
, …
'a list
Most computing problems involve data with more interesting structure: trees, graphs, matrices, vectors, tables, documents…
The OCaml type system lets us create new types that represent the operations and relationships in the data, and new values corresponding to these types.
Simplest case: a new name for an existing type
type
name
=
type-expr
This simple form doesn’t create new values, just a different name for an existing type.
Type abbreviations can be parameterized:
type 'a pair = 'a * 'a
Resulting in a type constructor, which takes a type as an argument, and produces a type:
int pair
, string pair
, (float list) pair
Multiple parameters are separated with commas:
type ('k, 'v) pair = 'k * 'v
We still haven’t introduced new types or values…
Record types are similar to “structs” or “classes” without inheritance:
Records are “product” types, but components of the tuple (fields) have names.
Example: phone book records
Records can be destructured / matched by patterns:
We can construct a new record from an old one:
An enumerated type declaration introduces a new type and new values:
type
name
=
Value1
|
Value2
| ... |
Value𝓀
For example:
Introduces the new type size
, and three values* that only belong to the type size
: Tall
, Grande
, Venti
.
* technically: value constructors. More next time…
We can use these values in pattern matching, just like built-in constants, e.g.
Define an enumerated type hogwarts_house
, and a function that maps a hogwarts_house
to a string describing its mascot.
Values of an enumerated type can be used with =
, <>
, <
, >
…
Results are dependent on the order of the type declaration, and shouldn’t be relied on.
Define hcompare : hogwarts_house -> hogwarts_house -> int
that returns:
-1
if h1 < h2
,0
if h1 = h2
and+1
if h1 > h2
,where Hufflepuff < Gryffindor < Ravenclaw < Slytherin
:
cs2041.org