CS 3110 Lecture 4
Variant types and polymorphism
Variant types
Lists are very useful, but it turns out they are not really as special as they look. We can implement our own
lists, and other more interesting data structures, such as binary trees.
In recitation you should have seen some simple examples of
variant types
sometimes known as
algebraic
datatypes
or just
datatypes
. Variant types provide some needed power: the ability to have a variable that
contains more than one kind of value.
Unlike tuple types and function types, but like record types, variant types cannot be anonymous; they must be
declared with their names. Suppose we had a variable that could be contain yes, no, or maybe. Its type could
be declared as a variant type:
# type answer = Yes  No  Maybe;;
type answer = Yes  No  Maybe
# let x: answer = Yes;;
val x: ans = Yes
The variant type is declared with a set of
constructors
that describe the possible ways to make a value of that
type. In this case, we have three constructors:
Yes
,
No
, and
Maybe
. Constructor names must start with a
capital letter, and all other names in OCaml cannot start with a capital.
The different constructors can also carry values with them. For example, suppose we want a type that can
either be a 2D point or a 3D point. It can be declared as follows:
type eitherPoint = TwoD of float * float
 ThreeD of float * float * float
Some examples of values of type
eitherPoint
are:
TwoD(2.1, 3.0)
and
ThreeD(1.0, 0.0,
1.0)
.
Suppose we have a value of type
eitherPoint
. We need to find out which constructor it was made from
in order to get at the point data inside. This can be done using matching:
let p: eitherPoint = ...
in
match p with
TwoD(x, y) > ...
 ThreeD(x, y, z) > ...
Variant type syntax
We use
X
as a metavariable to represent the name of a constructor, and
T
to represent the name of a type.
Optional syntactic elements are indicated by brackets []. Then a variant type declaration looks like this in
general:
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
type
T
=
X
1
[
of
t
1
]  ... 
X
n
[
of
t
n
]
Variant types introduce new syntax for terms
e
, patterns
p
, and values
v
:
e
::= ... 
X
(
e
)

match
e
with
p
1
>
e
1
 ... 
p
n
>
e
n
p
::=
X

X
(
x
1
:
t
1
...
,
x
n
:
t
n
)
v
::=
c
 (
v
1
,...,
v
n
) 
fun
p
>
e

X
(
v
)
Note that the vertical bars in the expression "
match
e
with
p
1
>
e
1
 ... 
p
n
>
e
n
" are part the syntax of this
construct; the other vertical bars () are part of the BNF notation.
We can use variant types to define many useful data structures. In fact, the
bool
is really just a variant type
with constructors named
true
and
false
.
Implementing integer lists
We can write our own version of lists using variant types. Suppose we want to define values that act like
linked lists of integers. A linked list is either empty, or it has an integer followed by another list containing
the rest of the list elements. This leads to a very natural variant type declaration:
type intlist = Nil  Cons of (int * intlist)
This type has two constructors,
Nil
and
Cons
. It is a
recursive type
because it mentions itself in its own
definition (in the
Cons
constructor), just like a recursive function is one that mentions itself in its own
definition.
This is the end of the preview.
Sign up
to
access the rest of the document.
 '07
 GIAMBATTISTA,A

Click to edit the document details