Любой день недели
Мы легко можем использовать алгебраические типы данных для того, чтобы создавать перечисления, и классы типов Enum и Bounded помогают нам в этом. Рассмотрим следующий тип:
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
Так как все конструкторы значений нульарные (не принимают параметров, то есть не имеют полей), допустимо сделать для нашего типа экземпляр класса Enum. Класс типов Enum предназначен для типов, для значений которых можно определить предшествующие и последующие элементы. Также мы можем определить для него экземпляр класса Bounded – он предназначен для типов, у которых есть минимальное и максимальное значения. Ну и уж заодно давайте сделаем для него экземпляры всех остальных классов типов, которые можно сгенерировать автоматически, и посмотрим, что это даст.
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
deriving (Eq, Ord, Show, Read, Bounded, Enum)
Так как для нашего типа автоматически сгенерированы экземпляры классов Show и Read, можно конвертировать значения типа в строки и из строк:
ghci> Wednesday
Wednesday
ghci> show Wednesday
"Wednesday"
ghci> read "Saturday" :: Day
Saturday
Поскольку он имеет экземпляры классов Eq и Ord, допускаются сравнение и проверка на равенство:
ghci> Saturday == Sunday
False
ghci> Saturday == Saturday
True
ghci> Saturday > Friday
True
ghci> Monday `compare` Wednesday
LT
Наш тип также имеет экземпляр класса Bounded, так что мы можем найти минимальный и максимальный день.
ghci> minBound :: Day
Monday
ghci> maxBound :: Day
Sunday
Благодаря тому что тип имеет экземпляр класса Enum, можно получать предшествующие и следующие дни, а также задавать диапазоны дней.
ghci> succ Monday
Tuesday
ghci> pred Saturday
Friday
ghci> [Thursday .. Sunday]
[Thursday,Friday,Saturday,Sunday]
ghci> [minBound .. maxBound] :: [Day]
[Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday]
Замечательно!