Здесь >x
берётся из списка >[1,2,3]
, а >y
– из списка >[10,100,1000]
. Эти два списка комбинируются следующим образом. Во-первых, >x
становится равным 1, а >y
последовательно принимает все значения из списка >[10,100,1000]
. Поскольку значения >x
и >y
складываются, в начало результирующего списка помещаются числа >11
, >101
и >1001
(>1
прибавляется к >10
, >100
, >1000
). После этого >x
становится равным >2
и всё повторяется, к списку добавляются числа >12
, >102
и >1002
. То же самое происходит для >x
равного >3
.
Таким образом, каждый элемент >x
из списка >[1,2,3]
всеми возможными способами комбинируется с каждым элементом >y
из списка >[10,100,1000]
, а >x+y
используется для построения из этих комбинаций результирующего списка.
Вот другой пример: если у нас есть два списка >[2,5,10]
и >[8,10,11]
, и мы хотим получить произведения всех возможных комбинаций из элементов этих списков, то можно использовать следующее выражение:
>ghci> [x*y | x <– [2,5,10], y <– [8,10,11]]
>[16,20,22,40,50,55,80,100,110]
Как и ожидалось, длина нового списка равна 9.
Допустим, нам потребовались все возможные произведения, которые больше 50:
>ghci> [x*y | x <– [2,5,10], y <– [8,10,11], x*y > 50]
>[55,80,100,110]
А как насчёт списка, объединяющего элементы списка прилагательных с элементами списка существительных… с довольно забавным результатом?
>ghci> let nouns = ["бродяга","лягушатник","поп"]
>ghci> let adjs = ["ленивый","ворчливый","хитрый"]
>ghci> [adj ++ " " ++ noun | adj <– adjs, noun <– nouns]
>["ленивый бродяга","ленивый лягушатник","ленивый поп",
>"ворчливый бродяга","ворчливый лягушатник", "ворчливый поп",
>"хитрый бродяга","хитрый лягушатник","хитрый поп"]
Генераторы списков можно применить даже для написания своей собственной функции >length
! Назовём её >length'
: эта функция будет заменять каждый элемент списка на 1, а затем мы все эти единицы просуммируем функцией >sum
, получив длину списка:
>length' xs = sum [1 | _ <– xs]
Символ >_
означает, что нам неважно, что будет получено из списка, поэтому вместо того, чтобы писать имя образца, которое мы никогда не будем использовать, мы просто пишем >_
. Поскольку строки – это списки, генератор списков можно использовать для обработки и создания строк. Вот функция, которая принимает строку и удаляет из неё всё, кроме букв в верхнем регистре:
>removeNonUppercase st = [c | c <– st, c `elem` ['А'..'Я']]
Всю работу здесь выполняет предикат: символ будет добавляться в новый список, только если он является элементом списка >['А'..'Я']
. Загрузим функцию в GHCi и проверим:
>ghci> removeNonUppercase "Ха-ха-ха! А-ха-ха-ха!"