Skip to content
AgileLogics
4 min read

Tuples

Prerequisites: Lists

A tuple groups a fixed number of values that can have different types:

main :: IO ()
main = do
  let person = ("Ada", 36) :: (String, Int)
      point = (3.0, 4.0, 5.0) :: (Double, Double, Double)
  print person
  print (fst person, snd person)
  print point
  let (name, age) = person
  putStrLn (name ++ " will be " ++ show (age + 1) ++ " next year")
("Ada",36)
("Ada",36)
(3.0,4.0,5.0)
Ada will be 37 next year
Lists Tuples
Any length Fixed length, part of the type
All elements the same type Elements can differ
[Int] (String, Int)
  • fst and snd work only on pairs. For bigger tuples, use pattern matching: let (x, y, z) = point.
  • (String, Int) and (Int, String) are different types.

Returning several values

Tuples are the easy way to return more than one result:

minMax :: [Int] -> (Int, Int)
minMax xs = (minimum xs, maximum xs)

divide :: Int -> Int -> (Int, Int)
divide a b = (a `div` b, a `mod` b)

main :: IO ()
main = do
  print (minMax [4, 9, 1, 7])
  let (q, r) = divide 17 5
  putStrLn ("17 = 5 * " ++ show q ++ " + " ++ show r)
  print (divMod 17 5)
(1,9)
17 = 5 * 3 + 2
(3,2)

divMod from the Prelude does exactly what divide does.

Lists of tuples

main :: IO ()
main = do
  let inventory = [("apples", 12), ("pears", 0), ("plums", 7)]
  print [item | (item, count) <- inventory, count > 0]
  print (sum (map snd inventory))
["apples","plums"]
19

When tuples start carrying more than two or three fields, or appear everywhere in your program, define a record type instead (Level 2) — named fields are much clearer than remembering what position 3 means.