Главная » Haskell » Синонимы типов

0

используются для упрощения записей имён типов. Иногда типы некоторых выражений являются достаточно сложными. Это может происходить при использовании алгебраических типов данных, в конструкторах которых используется  большое количество типов, либо в типах функций. Для того чтобы исключить многократное повторение одинаковых длинных последовательностей, можно определять синонимы типов. Эта техника также полезна и в качестве объявления единственной программной сущности, для изменения которой в случае необходимости вносить изменения было бы можно только в одном месте программного кода.

Синонимы определяются при помощи ключевого слова type. После него записывается наименование синонима типа с заглавной буквы и перечисляются переменные типов, если это необходимо. После записывается символ (=) и выражение, определяющее тип. Если используются переменные типов, то все они должны использоваться в выражении типа. Например, следующие синонимы можно определить для разных нужд:

type  List a = [a]

type  ListInteger =  [Integer]  type  Function a b = a ->  b

Использование синонимов типов имеет определённые ограничения. Например, их конструкторы невозможно частично применять к своим аргументам, в то время как конструкторы алгебраических типов данных можно. Рекурсивные алгебраические типы данных допустимы, а синонимы типов нет. Взаимно рекурсивные синонимы типов возможны только при использовании промежуточных алгебраических типов данных. Например, определения:

type  Record a = [Circular a]

data  Circular a = Tag [Record  a]

возможны, в то время как определения:

type  Record a =  [Circular a] type  Circular a =  [Record  a]

вызовут ошибку.

представляют собой удобный, но строго синтаксический механизм, который делает сигнатуры программных сущностей  более читабельными. Синоним и его определение,   — полностью взаимозаменяемы. Единственное место, где нельзя использовать синоним типа вместо самого типа, который заменяется синонимом  — определения экземпляров  классов.  В них можно использовать только сами типы.

Однако в языке Haskell имеется один специальный синоним, который поддерживается на уровне трансляторов. Этот синоним — String, который определён следующим образом:

type  String = [Char]

Да, строки в языке Haskell являются просто списками символов (тип Char), ни больше ни меньше. Единственное, чем этот синоним отличается от прочих — особая поддержка на уровне синтаксиса. В целях экономии усилий и нервов разработчиков программного обеспечения создатели языка Haskell позволили записывать строки в виде собственно строк, заключённых в кавычки ("). Ибо было бы очень неудобно записывать строки примерно следующим образом:

[’H’, ’e’, ’l’, ’l’, ’o’, ’,’, ’ ’, ’w’, ’o’, ’r’, ’l’, ’d’, ’!’]

Эта запись абсолютно тождественна такой: "Hello, world!"

2.4.         Параметрический  полиморфизм

При использовании параметрического полиморфизма конструкторы алгебраических типов данных могут быть определены достаточно обобщённо для того, чтобы тип содержал внутри себя значения совершенно различных типов. Эта техника уже  неоднократно неявно  использовалась в приводимых примерах, когда вместо конкретных типов данных внутри конструктора использовались некоторые переменные, обычно обозначаемые строчными буквами латинского алфавита, начиная с его начала, например a, b и т. д.

Вместо таких переменных может быть подставлен любой тип, чтобы конкретизировать полиморфный алгебраический тип данных. Интуитивно это должно быть понятно: такой тип данных, как, к примеру, список, может содержать внутри себя данные любого типа. Как это записать? Конечно, используя  переменные типов:

data  List a

= Nil

| Cons a (List  a)

При определении полиморфного алгебраического типа данных  необходимо помнить об одном непререкаемом правиле. Если  какой-либо  (или какие-либо) конструктор данных использует переменные типа, то все эти переменные должны быть перечислены после наименования типа перед символом (=). Это правило ограничивает использование переменных типа с одинаковым наименованием в разных смыслах в разных конструкторах одного и того же алгебраического типа данных. Поэтому при конкретизации типа, представленного  переменной, она заменяется конкретным типом везде, где имеет вхождение.

Язык Haskell поддерживает различные виды полиморфизма данных и функций. В этом разделе был рассмотрен только параметрический полиморфизм алгебраических типов данных, но в дальнейшем изложении будут упомянуты иные виды полиморфизма: ограничение контекстом использования и перегрузка имён функций (полиморфизм ad-hoc). Все они будут кратко описаны в соответствующих разделах главы 3..

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии