Изучай Haskell во имя добра! (Липовача) - страница 26

ПРИМЕЧАНИЕ. Идентификатор >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 являются последовательно упорядоченные типы; их значения можно перенумеровать. Основное преимущество класса типов >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 интересны тем, что имеют тип