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

, то получим ошибку, потому что мы попытались сложить значения типа >Int и число с плавающей точкой. В этом случае можно использовать функцию >fromIntegral:

>ghci> fromIntegral (length [1,2,3,4]) + 3.2

>7.2

Несколько заключительных слов о классах типов

Поскольку класс типа определяет абстрактный интерфейс, один и тот же тип данных может иметь экземпляры для различных классов, а для одного и того же класса могут быть определены экземпляры различных типов. Например, тип >Char имеет экземпляры для многих классов, два из которых – >Eq и >Ord, поскольку мы можем сравнивать символы на равенство и располагать их в алфавитном порядке.

Иногда для типа данных должен быть определён экземпляр некоторого класса для того, чтобы имелась возможность определить для него экземпляр другого класса. Например, для определения экземпляра класса >Ord необходимо предварительно иметь экземпляр класса >Eq. Другими словами, наличие экземпляра класса >Eq является предварительным (необходимым) условием для определения экземпляра класса >Ord. Если поразмыслить, это вполне логично: раз уж допускается расположение неких значений в определённом порядке, то должна быть предусмотрена и возможность проверить их на равенство.

3

Синтаксис функций

Сопоставление с образцом


В этой главе будет рассказано о некоторых весьма полезных синтаксических конструкциях языка Haskell, и начнём мы с сопоставления с образцом. Идея заключается в указании определённых шаблонов – образцов, которым должны соответствовать некоторые данные. Во время выполнения программы данные проверяются на соответствие образцу (сопоставляются). Если они подходят под образец, то будут разобраны в соответствии с ним.

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

>lucky :: Int -> String

>lucky 7 = "СЧАСТЛИВОЕ ЧИСЛО 7!"

>lucky x = "Прости, друг, повезёт в другой раз!"

Когда вы вызываете функцию >lucky, производится проверка параметра на совпадение с заданными образцами в том порядке, в каком они были заданы. Когда проверка даст положительный результат, используется соответствующее тело функции. Единственный случай, когда число, переданное функции, удовлетворяет первому образцу, – когда оно равно семи. В противном случае проводится проверка на совпадение со следующим образцом. Следующий образец может быть успешно сопоставлен с любым числом; также он привязывает переданное число к переменной