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". В тексте книги для большей понятности кириллица в результатах оставлена без изменений. –