ПРИМЕЧАНИЕ. Идентификатор >String
– альтернативное наименование типа >[Char]
. Идентификаторы >String
и >[Char]
могут быть использованы взаимозаменяемо, но далее будет использоваться только >String
, поскольку это удобнее и писать, и читать.
Видите? Функция возвращает тип, имеющий экземпляр класса >Read
, но если мы не воспользуемся им позже, то у компилятора не будет способа определить, какой именно это тип. Вот почему используются явные аннотации типа. Аннотации типа – способ явно указать, какого типа должно быть выражение. Делается это с помощью добавления символов >::
в конец выражения и указания типа. Смотрите:
>ghci> read "5" :: Int
>5
>ghci> read "5" :: Float
>5.0
>ghci> (read "5" :: Float) * 4
>20.0
>ghci> read "[1,2,3,4]" :: [Int]
>[1,2,3,4]
>ghci> read "(3, 'a')" :: (Int, Char)
>(3, 'a')
Для большинства выражений компилятор может вывести тип самостоятельно. Но иногда он не знает, вернуть ли значение типа >Int
или >Float
для выражения вроде >read "5"
. Чтобы узнать, какой у него тип, язык Haskell должен был бы фактически вычислить >read "5"
.
Но так как Haskell – статически типизированный язык, он должен знать все типы до того, как скомпилируется код (или, в случае GHCi, вычислится). Так что мы должны сказать языку: «Эй, это выражение должно иметь вот такой тип, если ты сам случайно не понял!»
Обычно компилятору достаточно минимума информации, чтобы определить, значение какого именно типа должна вернуть функция >read
. Скажем, если результат функции >read
помещается в список, то Haskell использует тип списка, полученный благодаря наличию других элементов списка:
>ghci> [read "True" , False, True, False]
>[True, False, True, False]
Так как >read
>"True"
используется как элемент списка булевых значений, Haskell самостоятельно определяет, что тип >read "True"
должен быть >Bool
.
Экземплярами класса >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'