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

>ghci> [0.1, 0.3 .. 1]

>[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]

Мой совет: не используйте такие числа в интервалах!

Интервалы, кроме прочего, можно использовать для создания бесконечных списков, просто не указывая верхний предел. Позже мы рассмотрим этот вариант в подробностях. А сейчас давайте посмотрим, как можно получить список первых 24 чисел, кратных 13. Конечно, вы могли бы написать >[13,26..24*13]. Но есть способ получше: >take 24 [13,26..]. Поскольку язык Haskell ленив, он не будет пытаться немедленно вычислить бесконечный список, потому что процесс никогда не завершится. Он подождёт, пока вы не захотите получить что-либо из такого списка. Тут-то обнаружится, что вы хотите получить только первые 24 элемента, что и будет исполнено.

Немного функций, производящих бесконечные списки:

• Функция >cycle принимает список и зацикливает его в бесконечный. Если вы попробуете отобразить результат, на это уйдёт целая вечность, поэтому вам придётся где-то его обрезать.

>ghci> take 10 (cycle [1,2,3])

>[1,2,3,1,2,3,1,2,3,1]

>ghci> take 12 (cycle "LOL ")

>"LOL LOL LOL "

• Функция >repeat принимает элемент и возвращает бесконечный список, состоящий только из этого элемента. Это подобно тому, как если бы вы зациклили список из одного элемента.

>ghci> take 10 (repeat 5)

>[5,5,5,5,5,5,5,5,5,5]

Однако проще использовать функцию >replicate, если вам нужен список из некоторого количества одинаковых элементов. >replicate 3 10 вернёт >[10,10,10].

Генераторы списков


Если вы изучали курс математики, то, возможно, сталкивались со способом задания множества путём описания характерных свойств, которыми должны обладать его элементы. Обычно этот метод используется для построения подмножеств из множеств.

Вот пример простого описания множества. Множество, состоящее из первых десяти чётных чисел, это S = {2 · x | x ∈ N, x ≤ 10}, где выражение перед символом | называется производящей функцией (output function), x – переменная, N – входной набор, а x ≤ 10 – условие выборки. Это означает, что множество содержит удвоенные натуральные числа, которые удовлетворяют условию выборки.

Если бы нам потребовалось написать то же самое на языке Haskell, можно было бы изобрести что-то вроде: >take 10 [2,4..]. Но что если мы хотим не просто получить первые десять удвоенных натуральных чисел, а применить к ним некую более сложную функцию? Для этого можно использовать генератор списков. Он очень похож на описание множеств:

>ghci> [x*2 | x <– [1..10]]

>[2,4,6,8,10,12,14,16,18,20]

В выражении >[x*2 | x <– [1..10]] мы извлекаем элементы из списка