import Prelude
(Bool(.. ), Show(.. ), Eq(.. ))true :: Bool
true = True
false :: Bool
false = False
not :: Bool -> Bool
not True
= False
not False = True
and :: Bool -> Bool -> Bool
and False
_
= False
and True
x
=
xor
:: Bool -> Bool -> Bool
or True
_ = True
or False
x =
xxor :: Bool -> Bool -> Bool
xor a b =
or (and (not a) b) (and a (not b))ifThenElse :: Bool ->
a -> a -> aifThenElse True
t
_ =
tifThenElse False
_
e =
eТеперь сохраним модуль и загрузим его в интерпретатор. Для наглядности мы установим флаг +
t, приэтом будет возвращено не только значение, но и его тип. Понабираем разные комбинации значений:
*Logic> :
l Logic[1 of
1] Compiling Logic( Logic.
hs, interpreted )Ok
, modules loaded: Logic.*Logic> :
set +t*Logic>
not (and true False)True
it :: Bool
*Logic>
or (and true true) (or False False)True
it :: Bool
*Logic>
xor (not True) (False)False
it :: Bool
*Logic>
ifThenElse (or true false) True FalseTrue
it :: Bool
Логические значения | 27
Разумеется в Haskell уже определены логические операции, здесь мы просто тренировались. Они называ-
ются not, (&&
), ||. Операция xor это то же самое, что и (/=). Для Bool определён экземпляр класса Eq. Такжев Haskell есть конструкция ветвления она пишется так:
x = if
cond then t else eСлова if
, then и else – ключевые. cond имеет тип Bool, а t и e одинаковый тип.В коде программы обычно пишут так:
x = if
a > 3then
”Hello”else
(if a < 0then
”Hello”else
”Bye”)Отступы обязательны.
Давайте загрузим в интерпретатор модуль Prelude
и наберём те же выражения стандартными функция-ми:
*Logic> :
m PreludePrelude>
not (True && False)True
it :: Bool
Prelude>
(True && True) || (False || False)True
it :: Bool
Prelude>
not True /= FalseFalse
it :: Bool
Prelude> if
(True || False) then True else FalseTrue
it :: Bool
Бинарные операции с символьными именами пишутся в инфиксной форме, то есть между аргументами
как в a &&
b или a + b. Значение с буквенным именем также можно писать в инфиксной форме, для этогооно заключается в апострофы, например a ‘and‘ b или a ‘plus‘ b. Апострофы обычно находятся на одной
кнопке с буквой “ё”. Также символьные функции можно применять в префиксной форме, заключив их в
скобки, например (&&
) a b и (+) a b. Попробуем в интерпретаторе:Prelude> True && False
False
it :: Integer
Prelude>
(&& ) True FalseFalse
it :: Bool
Prelude> let
and a b = a && band :: Bool -> Bool -> Bool
Prelude>
and True FalseFalse
it :: Bool
Prelude> True
‘and‘ FalseFalse
it :: Bool
Обратите внимание на строчку let
and a b = a && b. В ней мы определили синоним в интерпретаторе.Сначала мы пишем ключевое слово let
затем обычное определение синонима, как в программе. Это простоеоднострочное определение, но мы можем набирать в интерпретаторе и более сложные. Мы можем написать
несколько строчек в одной, разделив их точкой с запятой:
Prelude> let
not2 True = False; not2 False = TrueМы можем записать это определение более наглядно, совсем как в редакторе, если воспользуемся много-
строчным вводом. Для этого просто наберите команду :
{. Для выхода воспользуйтесь командой :}. Отметим,что точкой с запятой можно пользоваться и в обычном коде. Например в том случае если у нас много кратких
определений и мы хотим записать их покомпактней, мы можем сделать это так:
a1 =
1;a2 =
2;a3 =
3a4 =
4;a5 =
5;a6 =
628 | Глава 2: Первая программа
2.4 Класс Show. Строки и символы
Мы набираем в интерпретаторе какое-нибудь сложное выражение, или составной синоним, интерпрета-
тор проводит редукцию и выводит ответ на экран. Откуда интерпретатор знает как отображать значения
типа Bool
? Внутри интерпретатора вызывается метод класса Show, который переводит значение в строку. Изатем мы видим на экране ответ.
Для типа Bool
экземпляр класса Show уже определён, поэтому интерпретатор знает как его отображать.Обратите внимание на эту особенность языка, вид значения определяется пользователем, в экземпляре
класса Show
. Из соображений наглядности вид значения может сильно отличаться от его внутреннего пред-ставления.
В этом разделе мы рассмотрим несколько примеров с классом Show
, но перед этим мы поговорим о стро-ках и символах в языке Haskell.
Строки и символы
Посмотрим в интерпретаторе на определение строк (тип String
), для этого мы воспользуемся командой:
i (сокращение от :info):Prelude> :
i String