Сравнение людей на равенство
Рассмотрим такой тип данных:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
}
Тип описывает человека. Предположим, что среди людей не встречаются тёзки одного возраста. Если у нас есть два описания, можем ли мы выяснить, относятся ли они к одному и тому же человеку? Есть ли в такой операции смысл? Конечно, есть. Мы можем сравнить записи и проверить, равны они или нет. Вот почему имело бы смысл определить для нашего типа экземпляр класса Eq. Порождаем экземпляр:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
} deriving (Eq)
Когда мы определяем экземпляр класса Eq для типа и пытаемся сравнить два значения с помощью операторов == или /=, язык Haskell проверяет, совпадают ли конструкторы значений (хотя в нашем типе только один конструктор), а затем проверяет все данные внутри конструктора на равенство, сравнивая каждую пару полей с помощью оператора ==. Таким образом, типы всех полей также должны иметь определённый экземпляр класса Eq. Так как типы полей нашего типа, String и Int, имеют экземпляры класса Eq, всё в порядке.
Запишем в файл несколько людей:
mikeD = Person {firstName = "Майкл", lastName = "Даймонд", age = 45}
adRock = Person {firstName = "Адам", lastName = "Горовиц", age = 45}
mca = Person {firstName = "Адам", lastName = "Яух", age = 47}
И проверим экземпляр класса Eq:
ghci> mca == adRock
False
ghci> mikeD == adRock
False
ghci> mikeD == mikeD
True
ghci> mca == Person {firstName = "Адам", lastName = "Яух", age = 47}
True
Конечно же, так как теперь тип Person имеет экземпляр класса Eq, мы можем передавать его любым функциям, которые содержат ограничение на класс типа Eq в декларации, например функции elem.
ghci> let beastieBoys = [mca, adRock, mikeD]
ghci> mikeD `elem` beastieBoys
True