Класс Num – это класс типов для чисел. Его экземпляры могут вести
себя как числа. Давайте проверим тип некоторого числа:
ghci> :t 20
20 :: (Num t) => t
Похоже, что все числа также являются полиморфными константами.
Они могут вести себя как любой тип, являющийся экземпляром
класса Num
(Int,
Integer,
Float
или Double).
ghci> 20 :: Int
20
ghci> 20 :: Integer
20
ghci> 20 :: Float
20.0
ghci> 20 :: Double
20.0
Если проверить тип оператора *, можно увидеть, что он принимает
любые числа.
ghci> :t (*)
(*) :: (Num a) => a –> a –> a
Он принимает два числа одинакового типа и возвращает число
этого же типа. Именно поэтому (5 :: Int) * (6 :: Integer) приведёт
к ошибке, а 5 * (6 :: Integer) будет работать нормально и вернёт
значение типа Integer потому, что 5 может вести себя и как Integer,
и как Int.
Чтобы присоединиться к классу Num, тип должен «подружиться»
с классами Show и Eq.