Так как >read
>"True"
используется как элемент списка булевых значений, Haskell самостоятельно определяет, что тип >read "True"
должен быть >Bool
.
Класс Enum
Экземплярами класса >Enum
являются последовательно упорядоченные типы; их значения можно перенумеровать. Основное преимущество класса типов >Enum
в том, что мы можем использовать его типы в интервалах списков. Кроме того, у них есть предыдущие и последующие элементы, которые можно получить с помощью функций >succ
и >pred
. Типы, входящие в этот класс: >()
, >Bool
, >Char
, >Ordering
, >Int
, >Integer
, >Float
и >Double
.
>ghci> ['a'..'e']
>"abcde"
>ghci> [LT .. GT]
>[LT,EQ,GT]
>ghci> [3 .. 5]
>[3,4,5]
>ghci>succ 'B'
>'C'
Класс Bounded
Экземпляры класса типов >Bounded
имеют верхнюю и нижнюю границу.
>ghci> minBound :: Int
>–2147483648
>ghci> maxBound :: Char
>'\1114111'
>ghci> maxBound :: Bool
>True
>ghci> minBound :: Bool
>False
Функции >minBound
и >maxBound
интересны тем, что имеют тип >(Bounded a) => a
. В этом смысле они являются полиморфными константами.
Все кортежи также являются частью класса >Bounded
, если их компоненты принадлежат классу >Bounded
.
>ghci> maxBound :: (Bool, Int, Char)
>(True,2147483647,'\1114111')
Класс Num
Класс >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
.
Класс Floating
Класс >Floating
включает в себя только числа с плавающей точкой, то есть типы >Float
и >Double
.
Функции, которые принимают и возвращают значения, являющиеся экземплярами класса >Floating
, требуют, чтобы эти значения могли быть представлены в виде числа с плавающей точкой для выполнения осмысленных вычислений. Некоторые примеры: функции >sin
, >cos
и >sqrt
.
Класс Integral
Класс >Integral
– тоже числовой класс типов. Если класс >Num
включает в себя все типы, в том числе действительные и целые числа, то в класс >Integral
входят только целые числа. Для типов >Int
и >Integer
определены экземпляры данного класса.
Очень полезной функцией для работы с числами является >fromIntegral
. Вот её объявление типа:
>fromIntegral :: (Num b, Integral a) => a –> b
Из этой сигнатуры мы видим, что функция принимает целое число >(Integral)
и превращает его как более общее число >(Num)
.
ПРИМЕЧАНИЕ. Необходимо отметить, что функция >fromIntegral
имеет несколько ограничений классов в своей сигнатуре. Такое вполне допустимо – несколько ограничений разделяются запятыми и заключаются в круглые скобки.