Ранее мы упоминали, что типы >[Char]
и >String
являются эквивалентами и могут взаимно заменяться. Это осуществляется с помощью синонимов типов. Синоним типа сам по себе ничего не делает – он просто даёт другое имя существующему типу, облегчая понимание нашего кода и документации. Вот так стандартная библиотека определяет тип >String
как синоним для >[Char]
:
>type String = [Char]
Ключевое слово >type
может ввести в заблуждение, потому что на самом деле мы не создаём ничего нового (создаём мы с помощью ключевого слова >data
), а просто определяем синоним для уже существующего типа.
Если мы создадим функцию, которая преобразует строку в верхний регистр, и назовём её >toUpperString
, то можем дать ей сигнатуру типа >toUpperString :: [Char] –> [Char]
или >toUpperString :: String –> String
. Обе сигнатуры обозначают одно и то же, но вторая легче читается.
Улучшенная телефонная книга
Когда мы работали с модулем >Data.Map
, то вначале представляли записную книжку в виде ассоциативного списка, а потом преобразовывали его в отображение. Как мы уже знаем, ассоциативный список – это список пар «ключ–значение». Давайте взглянем на этот вариант записной книжки:
>phoneBook :: [(String,String)]
>phoneBook =
> [("оля","555–29-38")
> ,("женя","452–29-28")
> ,("катя","493–29-28")
> ,("маша","205–29-28")
> ,("надя","939–82-82")
> ,("юля","853–24-92")
> ]
Мы видим, что функция >phoneBook
имеет тип >[(String,String)]
. Это говорит о том, что перед нами ассоциативный список, который отображает строки в строки, – но не более. Давайте зададим синоним типа, и мы сможем узнать немного больше по декларации типа:
>type PhoneBook = [(String,String)]
Теперь декларация типа для нашей записной книжки может быть такой: >phoneBook :: PhoneBook
. Зададим также синоним для >String
.
>type PhoneNumber = String
>type Name = String
>type PhoneBook = [(Name,PhoneNumber)]
Те, кто программирует на языке Haskell, дают синонимы типу >String
, если хотят сделать объявления более «говорящими» – пояснить, чем являются строки и как они должны использоваться.