Tuples hold a finite number of elements with differing types.
Start ghci and check the type of a few tuple values.
:t (1, True, "Moustache")
:t ("bridge", 'a', 1.23)
Haskell by default uses a nice syntax to construct tuples but it allows you to access and use the original constructors.
:t (,)
:t (,,,)
:t (,) 10 True
Fields from a tuple can be extracted using pattern matching.
Create the file Tup.hs with the following content. Load it to ghci and call them.
aTimesB :: (Int, Int) -> Int
aTimesB (a, b) = a*b
aConcatB :: (String, String) -> String
aConcatB (a, b) = a ++ b
The same functions could be implemented without the use of tuples.
aTimesB2 :: Int -> Int -> Int
aTimesB2 a b = a*b
aConcatB2 :: String -> String -> String
aConcatB2 a b = a ++ b
The difference is that in the first version you can not use partial application since the tuple value forces you to pass both of the parameters. There are two functions that let's you convert between these forms of functions.
aTimesB (3, 2) == (curry aTimesB) 3 2
aTimesB (3, 2) == (uncurry aTimesB2) (3, 2)
There are two basic functions that are frequently used. They are defined on tuples of two values. This might seem strange but in practice these tuples are used most of the time.
-- extract the first value from a tuple
fst :: (a, b) -> a
-- extract the second value from a tuple
snd :: (a, b) -> b
- Try to implement your version of fst and snd without using the functions defined in Prelude.
myFst ("moustache", 2) == "moustache"
mySnd ("moustache", 2) == 2
Tuples are essentially the same as product types without giving a separate name to the type and the fields.
- What is the type of the tuple corresponding to the Person product type?
data Person = P { name :: String, address :: String, age :: Int }
- Implement a function that extracts the name from the tuple.