Tuples
Key points
Types constructed from literal values
Anonymous types, but aliases can be defined to give them a name
Product types by definition
Hence the
*
sign in the type signature:A * B
Number of elements in the tuples:
👌 2 or 3 (
A * B * C
)⚠️ > 3 : possible but prefer Record
Order of elements is important
If
A
≠B
, thenA * B
≠B * A
Construction
Syntax of literals: a,b
or a, b
or (a, b)
Comma
,
: symbol dedicated to tuples in F#Spaces
Parentheses
()
may be necessary
⚠️ Pitfall: the symbol used is different for literals vs types
,
for literal*
for signatureE.g.
true, 1.2
→bool * float
Deconstruction
👍 Same syntax as construction
⚠️ All elements must appear in the deconstruction
→ Use _
(discard) to ignore one of the elements
let point = 1.0, 2.5
let x, y = point
let x, y = 1, 2, 3 // 💥 Error FS0001: Type incompatibility...
// ... Tuples have lengths other than 2 and 3
let result = System.Int32.TryParse("123") // (bool * int)
let _, value = result // Ignore the "bool"
Tuples in practice
Use cases
Use a tuple for a data structure:
Small: 2 to 3 elements
Light: no need for element names
Local: small scope
Tuples are immutable: → modifications are made by creating a new tuple
let addOneToTuple (x, y, z) = x + 1, y + 1, z + 1
Structural equality
Structural equality works by default, but only between 2 tuples of the same signature:
(1,2) = (1,2) // true
(1,2) = (0,0) // false
(1,2) = (1,2,3) // 💥 Error FS0001: Type incompatibility...
// ... Tuples have lengths other than 2 and 3
(1,2) = (1,(2,3)) // 💥 Error FS0001: This expression was supposed to have type `int`...
// ... but here it has type `'a * 'b`
Nesting
Tuples can be nested in bigger tuples using parentheses ()
let doublet = (true,1), (false, "a") // (bool * int) * (bool * string) → pair of pairs
let quadruplet = true, 1, false, "a" // bool * int * bool * string → quadruplet
doublet = quadruplet // 💥 Error FS0001: Type incompatibility...
Pattern matching
Patterns recognized with tuples:
let print move =
match move with
| 0, 0 -> "No move" // Constant 0
| 0, y -> $"Vertical {y}" // Variable y (!= 0)
| x, 0 -> $"Horizontal {x}"
| x, y when x = y -> $"Diagonal {x}" // Condition x and y equal
// `x, x` is not a recognized pattern ❗
| x, y -> $"Other ({x}, {y})"
☝ Notes:
Patterns are ordered from specific to generic
The last pattern
x, y
is the default one to deconstruct a tuple
Pairs
2-element tuples
So common that 2 helpers are associated with them:
fst
as first to extract the 1st element of the pairsnd
as second to extract the 2nd element of the pair⚠️ Only works for pairs
let pair = 'a', "b"
fst pair // 'a' (char)
snd pair // "b" (string)
🕹️ Quiz
1. Implement fst
and snd
let fst ... ?
let snd ... ?
2. What is the signature of this function?
let toList (x, y) = [x; y]
Last updated
Was this helpful?