Another feature of the
F# language that I
crave desperately when writing C#
or VB code is F#'s built-in support for
tuples.
What's a tuple? Simply put, a tuple is an
ordered group of values. In one sense, a tuple is very similar to the
anonymous types of C# 3.0. The chief difference is
that the values in an F# tuple are not named like the properties of a C#
anonymous type.
NeRd Note
Most pressing on your mind is likely the
question of how one pronounces the word,
"tuple." Well, my
British friends
emphatically point out that it's "too-pull," while my
red-blooded, English-language-abusing American friends1 like to say "tuh-pull."
2
However, when my British friends speak, they always sound intelligent. I think
it has
something to do with the accent. So, I'm going with "too-pull." I like to sound
smart—especially when it's easy.
In F#, a tuple3 is concisely declared as a let statement
with a single name and multiple values separated by commas.
> let pair = 37, 5;;
val pair = int * int
> pair;;
val it : int * int = (37, 5)
Notice that F# infers the type of pair to be int * int.
The asterisk (*) doesn't actually mean multiplication
in this case.
Instead, it indicates that the two types on either side are bound together as one type.
Tuples can contain any number of values, and the values don't have to be of
the same type.
> let triple = 0, "F# Rules!", 12.8;;
val triple : int * string * float
Tuples can be compared for equality.
> pair = (29, 13);;
val it : bool = false
> pair = (37, 5);;
val it : bool = true
> pair = (19, 23);;
val it : bool = false
And other comparisons are also legal.
> (1, 1) < (1, 2);;
val it : bool = true
> (2, 1) > (1, 2);;
val it : bool = true
However, tuples with different types cannot be compared. Trying to compare
pair, which is of type int * int, with a tuple of type int * string results in an error:
> pair = (0, "F# Rules!");;
pair = (0, "F# Rules!");;
-----------^^^^^^^^^^^^
stdin(12,11): error: FS0001: This expression has type
string
but is here used with type
int
stopped due to error
In addition, tuples of different lengths cannot be compared.
> triple = (0, "F# Rules!");;
triple = (0, "F# Rules!");;
----------^^^^^^^^^^^^^^^
stdin(13,10): error: FS0001: Type mismatch. Expecting a
int * string * float
but given a
'a * 'b.
The tuples have different lengths
stopped due to error
Interestingly, in the above code, the F# compiler doesn't bother inferring the types in the tuple, (0, "F# Rules!").
It is left generic: 'a * 'b. The F# compiler sees that
the tuples have a different number of values and stops.
Next time we'll look at some cool ways to use tuples in F#
programming.
1Please don't hurt me Keith!
2Usually while sucking down a can of
Schlitz.
3too-pull