rec02 - Recitation 2: Tuples, records and datatypes Tuples...

Info iconThis preview shows pages 1–3. Sign up to view the full content.

View Full Document Right Arrow Icon
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 2-tuple (also known as an ordered pair.) In general, an n-tuple 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 3-tuple 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 2-tuple (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 n-tuple 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 3-tuple (42, "hello", true) has type (int * string * bool) . Notice that max1 has type (float*float)->float , indicating that it takes one argument (a 2-tuple 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
Background image of page 1

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
that -> is right-associative, which will come up when higher-order 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.
Background image of page 2
Image of page 3
This is the end of the preview. Sign up to access the rest of the document.

This note was uploaded on 10/25/2009 for the course PHYS 2214 at Cornell University (Engineering School).

Page1 / 9

rec02 - Recitation 2: Tuples, records and datatypes Tuples...

This preview shows document pages 1 - 3. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online