a6 =6
28 | Глава 2: Первая программа
2.4 Класс Show. Строки и символы
Мы набираем в интерпретаторе какое-нибудь сложное выражение, или составной синоним, интерпрета-
тор проводит редукцию и выводит ответ на экран. Откуда интерпретатор знает как отображать значения
типа Bool? Внутри интерпретатора вызывается метод класса Show, который переводит значение в строку. И
затем мы видим на экране ответ.
Для типа Boolэкземпляр класса Showуже определён, поэтому интерпретатор знает как его отображать.
Обратите внимание на эту особенность языка, вид значения определяется пользователем, в экземпляре
класса Show. Из соображений наглядности вид значения может сильно отличаться от его внутреннего пред-
ставления.
В этом разделе мы рассмотрим несколько примеров с классом Show, но перед этим мы поговорим о стро-
ках и символах в языке Haskell.
Строки и символы
Посмотрим в интерпретаторе на определение строк (тип String), для этого мы воспользуемся командой
:i (сокращение от :info):
Prelude> :i String
type String =[ Char]
-- Defined in ‘GHC.Base’
Интерпретатор показал определение типа и в комментариях указал в каком модуле тип определён. В
этом определении мы видим новое ключевое слово type. До этого для определения типов нам встречалось
лишь слово data. Ключевое слово typeопределяет синоним типа. При этом мы не вводим новый тип, мы
лишь определяем для него псевдоним. Stringявляется синонимом для списка значений типа Char. Тип
Charпредставляет символы. Итак строка – это список символов. В Haskell символы пишутся в ординарных
кавычках, а строки в двойных:
Prelude>[’H’,’e’,’l’,’l’,’o’]
”Hello”
it ::[ Char]
Prelude>”Hello”
”Hello”
it ::[ Char]
Prelude>’+’
’+’
it :: Char
Для обозначения перехода на новую строку используется специальный символ \n. Если строка слишком
длинная и не помещается на одной строке, то её можно перенести так:
str =”My long long long long \
\long long string”
Перенос осуществляется с помощью комбинации следующих друг за другом обратных слэшей.
Нам понадобится функция конкатенации списков ( ++), она определена в Prelude, с её помощью мы будем
объединять строки:
Prelude> :t ( ++)
( ++) ::[a] ->[a] ->[a]
Prelude>”Hello” ++[’ ’] ++”World”
”Hello World”
it ::[ Char]
Пример: Отображение дат и времени
Приведём, пример в котором отображаемое значение не совпадает с видом значения в коде. Мы отобра-
зим значения из мира календаря. Для начала давайте сохраним определения в отдельном модуле:
module Calendar where
import Prelude( Int, Char, String, Show( ..), ( ++))
-- Дата
Класс Show. Строки и символы | 29
data Date = Date Year Month Day
-- Год
data Year
= Year Int
-- Int это целые числа
-- Месяц
data Month
= January
| February
| March
| April
| May
| June
| July
| August
| September
| October
| November | December
data Day = Day Int
-- Неделя
data Week
= Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
-- Время
data Time = Time Hour Minute Second
data Hour
= Hour
Int
-- Час
data Minute = Minute Int
-- Минута
data Second = Second Int
-- Секунда
Теперь сохраним наш модуль под именем Calendar.hs и загрузим в интерпретатор:
Prelude> :l Calendar
[1 of1] Compiling Calendar
( Calendar.hs, interpreted )
Ok, modules loaded : Calendar.
*Calendar> Monday
<interactive >:3 :1 :
No instancefor ( Show Week)
arising from a use of‘ System.IO.print’
Possiblefix :add an instancedeclaration for ( Show Week)
Ina stmt ofan interactive GHCicommand : System.IO.print it
Смотрите мы попытались распечатать значение Monday, но в ответ получили ошибку. В ней интерпре-
татор сообщает нам о том, что для типа Weekне определён экземпляр класса Show, и он не знает как его
Читать дальше