Recitation 2: Tuples, records and datatypes
Tuples
Every function in OCaml takes exactly one value and returns exactly one result. For instance, our
squareRoot
function takes one float value and returns one float value. The advantage of always taking
one argument and returning one result is that the language is extremely uniform. Later, we'll see that this
buys us a lot when it comes to
composing
new functions out of old ones.
But it looks like we can write functions that take more than one argument! For instance, we may write:
let max1(r1, r2):float =
if r1 < r2 then r2
else r1
max1(3.1415, 2.718)
and it appears as if max1 takes two arguments. In truth max1 takes one argument that is a
2tuple
(also
known as an ordered pair.)
In general, an
ntuple
is an ordered sequence of
n
values written in parenthesis and separated by commas as
(
expr, expr,
...,
expr
). For instance,
(42, "hello", true)
is a 3tuple that contains the integer
42
as
its first component, the string
"hello"
as its second component, and the boolean value
true
as its third
component. As another example,
()
is the empty tuple. This is called "unit" in OCaml.
When you call a function in OCaml, if it takes more than one argument, then you have to pass it a tuple of the
arguments. For instance, when we write:
max1(3.1415, 2.718)
we're passing the 2tuple
(3.1415, 2.718)
to the function max1. We could just as well write:
val args = (3.1415, 2.178);
max1 args
(* evaluates to 3.1415 *)
The type of an ntuple is written
(
t
1
*
...
*
t
n
)
. For instance, the type of args above is
(float*float)
.
This notation is based on the Cartesian product in mathematics (i.e., the plane is R^2 = R * R).
Similarly, the 3tuple
(42, "hello", true)
has type
(int * string * bool)
. Notice that
max1
has type
(float*float)>float
, indicating that it takes one argument (a 2tuple of floats) and
returns one result (a float).
Combining what we've seen so far, we can write a grammar for the basic types as follows:
t
::=
int

float

bool

string

char

t
1
*
...
*
t
n

t
1
>
t
2

(
t
)
There are a few tricky parts to this. The two most important are that
>
has lower precedence than
*
, so the
types
(float*float)>float
and
float*float>float
are exactly the same type. The second is
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
that
>
is rightassociative, which will come up when higherorder functions are discussed.
You can extract the first two components of a tuple by using the
fst
and
snd
operators, which retreive the
first and second elements of a tuple, respectively. However, there are no analogous functions for the other
elements of a tuple.
So, for instance, we can rewrite the max function as follows:
let max1(pair:float*float):float =
if (fst pair) < (snd pair) then
(snd pair) else (fst pair)
and this is completely equivalent to the first definition. This emphasizes that
max
really does take just one
argument  a pair of floating point numbers. But of course, it's a lot less readable than the first definition.
This is the end of the preview.
Sign up
to
access the rest of the document.
 '07
 GIAMBATTISTA,A
 Tuple, Type theory, Pattern matching, Algebraic data type

Click to edit the document details