Part 18

Tuples

Before we dive into type classes, let’s introduce the last remaining built-in datatype in Haskell: the tuple. Tuples or pairs (or triples, quadruples, etc) are a way of bundling a couple of values of different types together. You can think of tuples as fixed-length lists (just like Python’s tuples). Unlike lists, each element in the tuple can have a different type. The types of the elements are reflected in the type of the tuple. Here are some examples of tuple types and values:

Type

Example value

(String,String)

("Hello","World!")

(Int,Bool)

(1,True)

(Int,Int,Int)

(4,0,3)

To get values out of tuples, you can use the functions fst and snd:

fst :: (a, b) -> a
snd :: (a, b) -> b

You can also pattern match on tuples. This is often the most convenient way, and also works for tuples of larger sizes. The fst and snd functions work only on pairs.

Tuples are very useful in combination with lists. Here are some examples using the zip, unzip and partition functions from the Data.List module.

zip :: [a] -> [b] -> [(a, b)]    -- two lists to list of pairs
unzip :: [(a, b)] -> ([a], [b])  -- list of pairs to pair of lists
partition :: (a -> Bool) -> [a] -> ([a], [a])    -- elements that satisfy and don't satisfy a predicate

zip [1,2,3] [True,False,True]
    ==> [(1,True),(2,False),(3,True)]
unzip [("Fred",1), ("Jack",10), ("Helen",13)]
    ==> (["Fred","Jack","Helen"],[1,10,13])
partition (>0) [-1,1,-4,3,2,0]
    ==> ([1,3,2],[-1,-4,0])

Here’s an example of pattern matching on tuples:

swap :: (a,b) -> (b,a)
swap (x,y) = (y,x)

Here’s an example of pattern matching on tuples and lists at the same time:

-- sum all numbers that are paired with True
sumIf :: [(Bool,Int)] -> Int
sumIf [] = 0
sumIf ((True,x):xs) = x + sumIf xs
sumIf ((False,_):xs) = sumIf xs

sumIf [(True,1),(False,10),(True,100)]
    ==> 101
You have reached the end of this section! Continue to the next section:

You can check your current points from the blue blob in the bottom-right corner of the page.