Изучай Haskell во имя добра! (Липовача) - страница 19

, потому что первый элемент списка – это пара чисел, а второй – пара, состоящая из строки и числа.

Кортежи также можно использовать для представления широкого диапазона данных. Например, если бы мы хотели представить чьё-либо полное имя и возраст в языке Haskell, то могли бы воспользоваться тройкой: >("Кристофер", "Уокен", 69). Как видно из этого примера, кортежи также могут содержать списки.

Используйте кортежи, когда вы знаете заранее, из скольких элементов будет состоять некоторая часть данных. Кортежи гораздо менее гибки, поскольку количество и тип элементов образуют тип кортежа, так что вы не можете написать общую функцию, чтобы добавить элемент в кортеж – понадобится написать функцию, чтобы добавить его к паре, функцию, чтобы добавить его к тройке, функцию, чтобы добавить его к четвёрке, и т. д.

Как и списки, кортежи можно сравнить друг с другом, если можно сравнивать их компоненты. Однако вам не удастся сравнить кортежи разных размеров (хотя списки разных размеров сравниваются, если можно сравнивать их элементы).

Несмотря на то что есть списки с одним элементом, не бывает кортежей с одним компонентом. Если вдуматься, это неудивительно. Кортеж с единственным элементом был бы просто значением, которое он содержит, и, таким образом, не давал бы нам никаких дополнительных возможностей[6].

Использование пар

Вот две полезные функции для работы с парами:

• >fst – принимает пару и возвращает её первый компонент.

>ghci> fst (8,11)

>8

>ghci> fst ("Вау", False)

>"Вау"

• >snd – принимает пару и возвращает её второй компонент. Неожиданно!

>ghci> snd (8,11)

>11

>ghci> snd ("Вау", False)

>False

ПРИМЕЧАНИЕ. Эти функции работают только с парами. Они не будут работать с тройками, четвёрками, пятёрками и т. д. Выделение данных из кортежей мы рассмотрим чуть позже.

Замечательная функция, производящая список пар, – >zip. Она принимает два списка и сводит их в один, группируя соответствующие элементы в пары. Это очень простая, но крайне полезная функция. Особенно она полезна, когда вы хотите объединить два списка или обойти два списка одновременно. Продемонстрируем работу >zip:

>ghci> zip [1,2,3,4,5] [5,5,5,5,5]

>[(1,5),(2,5),(3,5),(4,5),(5,5)]

>ghci> zip [1 .. 5] ["один", "два", "три", "четыре", "пять"]

>[(1,"один"),(2,"два"),(3,"три"),(4,"четыре"),(5,"пять")]

Функция «спаривает» элементы и производит новый список. Первый элемент идёт с первым, второй – со вторым и т. д. Обратите на это внимание: поскольку пары могут содержать разные типы, функция >zip может принять два списка, содержащих разные типы, и объединить их. А что произойдёт, если длина списков не совпадает?