Выбрать главу

ghci> (50 * 100) – 4999 1

ghci> 50 * 100 – 4999

1

ghci> 50 * (100 – 4999)

–244950

Здорово, правда? Чувствую, вы со мной не согласны, но немного терпения! Небольшая опасность кроется в использовании отрицательных чисел. Если нам захочется использовать отрицательные числа, то всегда лучше заключить их в скобки. Попытка выполнения 5 * –3 приведёт к ошибке, зато 5 * (–3) сработает как надо.

Булева алгебра в Haskell столь же проста. Как и во многих других языках программирования, в Haskell имеется два логических значения True и False, для конъюнкции используется операция && (логическое «И»), для дизъюнкции – операция || (логическое «ИЛИ»), для отрицания – операция not.

ghci> True && False False

ghci> True && True True

ghci> False || True True

ghci> not False

True

ghci> not (True&&True)

False

Можно проверить два значения на равенство и неравенство с помощью операций == и /=, например:

ghci> 5 == 5

True

ghci> 1 == 0

False

ghci> 5 /= 5

False

ghci> 5 /= 4

True

ghci> "привет" == "привет"

True

А что насчёт 5 + лама или 5 == True? Если мы попробуем выполнить первый фрагмент, то получим большое и страшное сообщение об ошибке[1]!

No instance for (Num [Char])

arising from a use of `+' at <interactive>:1:0–9

Possible fix: add an instance declaration for (Num [Char]) In the expression: 5 + "лама"

In the definition of `it': it = 5 + "лама"

Та-ак! GHCi говорит нам, что лама не является числом, и непонятно, как это прибавить к 5. Даже если вместо лама подставить четыре или 4, Haskell всё равно не будет считать это числом! Операция + ожидает, что аргументы слева и справа будут числовыми. Если же мы попытаемся посчитать True == 5, GHCi опять скажет нам, что типы не совпадают.

Несмотря на то что операция + производится только в отношении элементов, воспринимаемых как число, операция сравнения (==), напротив, применима к любой паре элементов, которые можно сравнить. Фокус заключается в том, что они должны быть одного типа. Вы не сможете сравнивать яблоки и апельсины. В подробностях мы это обсудим чуть позже.

ПРИМЕЧАНИЕ. Запись 5 + 4.0 вполне допустима, потому что 5 может вести себя как целое число или как число с плавающей точкой. 4.0 не может выступать в роли целого числа, поэтому именно число 5 должно «подстроиться».

Вызов функций

Возможно, вы этого пока не осознали, но всё это время мы использовали функции. Например, операция * – это функция, которая принимает два числа и перемножает их. Как вы видели, мы вызываем её, вставляя символ * между числами. Это называется «инфиксной записью».

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

ghci> succ 8 9

Функция succ принимает на вход любое значение, которое может иметь последующее значение, после чего возвращает именно последующее значение. Как вы видите, мы отделяем имя функции от параметра пробелом. Вызывать функции с несколькими параметрами не менее просто.

Функции min и max принимают по два аргумента, которые можно сравнивать (как и числа!), и возвращают большее или меньшее из значений:

ghci> min 9 10

9

ghci> min 3.4 3.2

3.2

ghci> max 100 101 101

Операция применения функции (то есть вызов функции с указанием списка параметров через пробел) имеет наивысший приоритет. Для нас это значит, что следующие два выражения эквивалентны:

ghci> succ 9 + max 5 4 + 1

16

ghci> (succ 9) + (max 5 4) + 1

16

Однако если мы хотим получить значение, следующее за произведением чисел 9 и 10, мы не можем написать succ 9 * 10, потому что это даст значение, следующее за 9 (т. е. 10), умноженное на 10, т. е. 100. Следует написать succ (9 * 10), чтобы получить 91.

вернуться

1

В современных версиях интерпретатора GHCi для печати результатов вычислений используется функция show, которая представляет кириллические символы соответствующими числовыми кодами Unicode. Поэтому в следующем листинге вместо строки "лама" будет фактически выведено "\1083\1072\1084\1072". В тексте книги для большей понятности кириллица в результатах оставлена без изменений. – Прим. ред.