Википедия

Полиморфизм типов

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

Параметрический полиморфизм считается «истинной» формой полиморфизма, делая язык более выразительным и существенно повышая коэффициент повторного использования кода. Традиционно ему противопоставляется ad-hoc-полиморфизм, предоставляющий единый интерфейс к потенциально различному коду для разных допустимых в данном контексте типов, потенциально не совместимых (статически или динамически). В ряде исчислений, например, в теории квалифицированных типов, ad-hoc-полиморфизм рассматривается как частный случай параметрического.

Параметрический полиморфизм лежит в основе систем типов языков семейства ML; такие системы типов называют полиморфными. В сообществах языков с неполиморфными системами типов (потомки Алгола и BCPL) параметрически полиморфные функции и типы называют «обобщёнными».

Полиморфизм типов

Термин «параметрический полиморфизм» традиционно используется для обозначения типобезопасного параметрического полиморфизма, хотя существуют и нетипизированные его формы (см. параметрический полиморфизм в Си и C++). Ключевым понятием типобезопасного параметрического полиморфизма, помимо полиморфной функции, является полиморфный тип.

Полиморфный тип (англ. polymorphic type), или политип (англ. polytype) — это тип, параметризованный другим типом. Параметр в слое типов называется переменной типа (или ти́повой переменной).

Формально полиморфизм типов изучается в полиморфно типизированном лямбда-исчислении, называемом Системой F.

Например, функция append, сцепляющая два списка в один, может быть построена независимо от типа элементов списка. Пусть ти́повая переменная a описывает тип элементов списка. Тогда функция append может быть типизирована как «forall a. [a] × [a] -> [a]» (здесь конструкция [a] означает тип «список, каждый элемент которого имеет тип a» — синтаксис, принятый в языке Haskell). В этом случае говорят, что тип параметризован переменной a для всех значений a. В каждом месте применения append к конкретным аргументам значение a разрешается, причём каждое её упоминание в [англ.] подменяется значением, соответствующим контексту применения. Таким образом, в данном случае сигнатура функционального типа требует идентичности типов элементов обоих списков и результата.

Множество допустимых значений переменной типа задаётся посредством квантификации. Простейшими кванторами являются универсальный (как в примере с append) и экзистенциальный (см. далее).

Квалифицированный тип (англ. qualified type) — это полиморфный тип, дополнительно снабжённый набором предикатов, регламентирующих спектр допустимых значений параметра этого типа. Иначе говоря, квалификация типа позволяет управлять квантификацией произвольным образом. Теорию квалифицированных типов построил Марк Джонс (Mark P. Jones) в 1992 году. Она предоставляет общее обоснование для самых экзотичных систем типов, включая классы типов, расширяемые записи и [англ.] и позволяет точно формулировать особые ограничения для конкретных полиморфных типов, устанавливая таким образом отношения между параметрическим и ad-hoc-полиморфизмом (перегрузкой), а также между явной и неявной перегрузкой. Связь типа с предикатом в этой теории называется свидетельством (англ. evidence). Для свидетельств сформулирована алгебра, аналогичная лямбда-исчислению, включающая абстракцию свидетельств, применение свидетельств и т. д. Соотнесение терма этой алгебры с явно перегруженной функцией называется трансляцией свидетельства (англ. evidence translation).

Мотивирующими примерами для разработки обобщённой теории послужили классы типов Вадлера — Блотта и типизация расширяемых записей посредством предикатов Харпера — Пирса.

Классификация полиморфных систем

Параметрически полиморфные системы типов принципиально классифицируются по рангу и по свойству предикативности. Кроме того, различаются явный и неявный полиморфизм и ряд других свойств. Неявный полиморфизм обеспечивается за счёт выведения типов, что существенно повышает удобство использования, но имеет ограниченную выразительность. Многие практические параметрически полиморфные языки разделяют фазы внешнего неявно типизированного языка (англ. external implicitly typed language) и внутреннего явно типизированного (англ. internal explicitly typed language).

Наиболее общей формой полиморфизма является «импредикативный полиморфизм высших рангов». Наиболее популярными ограничениями этой формы являются полиморфизм 1-го ранга, называемый «пренексным», и предикативный полиморфизм. Вместе они образуют «предикативный пренексный полиморфизм», близкий к реализованному в ML и в ранних версиях Хаскела.

С усложнением систем типов сигнатуры типов становятся настолько сложными, что полное или почти полное их выведение начинает рассматриваться многими исследователями как критичное свойство, отсутствие которого сделает язык непригодным для практики. Например, для традиционного комбинатора map полная сигнатура типа (с учётом родовой квантификации) в условиях типобезопасного отслеживания потока исключений принимает следующий вид (как и выше, [a] означает список элементов типа a):
image

Ранг

Ранг полиморфизма показывает допустимую в рамках системы глубину вложения кванторов переменных типа. «Полиморфизм ранга k» (при k > 1) позволяет конкретизировать переменные типа полиморфными типами ранга не выше (k — 1). «Полиморфизм высших рангов» позволяет ставить кванторы переменных типа слева от произвольного числа стрелок в типах высших порядков.

Джо Уэллс (англ. Joe Wells) доказал, что выведение типов для Системы F, типизированной по Карри, неразрешимо для рангов выше 2-го, так что при использовании более высоких рангов необходимо использовать явное аннотирование типами.

Существуют системы типов с частичным выведением, требующие аннотирования только невыводимых ти́повых переменных.

Пренексный полиморфизм

Полиморфизм ранга 1 часто называется пренексным (от слова «пренекс» — см. [англ.]). В пренексно полиморфной системе переменные типа не могут конкретизироваться полиморфными типами. Это ограничение делает различие между мономорфными и полиморфными типами существенным, из-за чего в пренексной системе полиморфные типы нередко называют «схемами типизации» (англ. type schemas) для отличения их от «обычных» (мономорфных) типов (монотипов). Как следствие, все типы могут быть записаны в форме, когда все кванторы переменных типа вынесены в самую внешнюю (пренексную) позицию, что и называется [англ.]. Проще говоря, разрешается полиморфное определение функций, но запрещается передавать полиморфные функции в качестве аргументов другим функциям — полиморфно определённые функции должны быть инстанцированы монотипом перед использованием.

Близким эквивалентом является так называемый «Let-полиморфизм» или «полиморфизм в стиле ML» Дамаса — Милнера. Технически, Let-полиморфизм в ML имеет дополнительные синтаксические ограничения, такие как «ограничение на значения» (value restriction), связанное с проблемой типобезопасности при использовании ссылок (не возникающих в чистых языках, таких как Haskell и Clean).

Предикативность

Предикативный полиморфизм

Предикативный (ограниченный условием) полиморфизм требует, чтобы переменная типа была конкретизирована монотипом (не политипом).

К предикативным системам относятся интуиционистская теория типов и [англ.].

Импредикативный полиморфизм

Импредикативный (безусловный) полиморфизм разрешает конкретизировать переменную типа произвольным типом — как мономорфным, так и полиморфным, включая сам определяемый тип. (Разрешение в рамках некоего исчисления рекурсивного включения системы в саму себя называется импредикативностью. Потенциально это может приводить к парадоксам типа Расселовского или Канторовского, но в случае с тщательно продуманной системой типов этого не происходит.)

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

Примером импредикативной системы является Система F и её расширения (см. лямбда-куб).

Поддержка рекурсии

Традиционно в потомках ML функция может быть полиморфной только при взгляде «извне» (то есть её можно применять к аргументам различных типов), но её определение может содержать только мономорфную рекурсию (то есть разрешение типов осуществляется до вызова). Распространение реконструкции типов по ML на рекурсивные типы не представляет серьезных трудностей. С другой стороны, сочетание реконструкции типов с рекурсивно определёнными термами порождает сложную проблему, известную под названием [англ.]. Майкрофт (Mycroft) и Мейртенс (Meertens) предложили полиморфное правило типизации, позволяющее конкретизировать различными типами рекурсивные вызовы рекурсивной функции из её собственного тела. В этом исчислении, известном как исчисление Милнера — Майкрофта, выведение типов неразрешимо.

Полиморфизм структурных типов

Типы-произведения (также известные как «записи») служат формальной базой для объектно-ориентированного и модульного программирования. Их двойственную пару составляют типы-суммы (также известные как «[англ.]»):

image
image

Вместе они являются средством выражения любых сложных структур данных и некоторых аспектов поведения программ.

Исчисление записей (англ. record calculi) — обобщённое название проблемы и ряда её решений, касающихся вопросов гибкости типов-произведений в языках программирования при условии типобезопасности. Термин нередко распространяется и на типы-суммы, а границы понятия «тип записи» могут варьироваться от исчисления к исчислению (как и само понятие «тип»). Применяются также термины «полиморфизм записей» (что, опять же, зачастую включает в себя полиморфизм вариантов), «исчисление модулей» и «структурный полиморфизм».

Общие сведения

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

Классическим примером может служить язык Standard ML, система типов которого была умышленно ограничена ровно настолько, чтобы сочетать простоту реализуемости с выразительностью и математически доказуемой типобезопасностью.

Пример определения записи:

> val r = {name = "Foo", used = true}; (* val r : {name : string, used : bool} = {name = "Foo", used = true} *) 

Доступ к значению поля по его имени осуществляется префиксной конструкцией вида #field record:

> val r1 = #name r; (* val r1 : string = "Foo" *) 

Следующее определение функции над записью является корректным:

> fun name1 (x: {name : string, age : int}) = #name x 

А следующее порождает ошибку компилятора о том, что тип не разрешён полностью:

> fun name2 x = #name x (* unresolved type in declaration:  {name : '1, ...} *) 

Мономорфизм записей делает их негибким, но эффективным средством: поскольку фактическое расположение в памяти каждого поля записи известно заранее (на этапе компиляции), обращение к нему по имени компилируется в прямую индексацию, что обычно вычисляется за одну машинную инструкцию. Однако, при разработке сложных масштабируемых систем желательно иметь возможность абстрагировать поля от конкретных записей — например, определить универсальный селектор полей:

fun select r l = #l r 

Но компиляция полиморфного обращения к полям, которые могут располагаться в разном порядке в разных записях, представляет сложную проблему, как с точки зрения контроля безопасности операций на уровне языка, так и с точки зрения быстродействия на уровне машинного кода. Наивным решением может быть динамический поиск по словарю при каждом обращении (и скриптовые языки его применяют), однако, очевидно, что это чрезвычайно неэффективно.

Суммы типов составляют основу выражения ветвления, причём за счёт строгости системы типов компилятор обеспечивает контроль за полнотой разбора. Например, для следующего типа-суммы:

datatype 'a foo = A of 'a | B of ('a * 'a) | C 

всякая функция над ним будет иметь вид

fun bar (p:'a foo) = case p of A x => ... | B (x,y) => ... | C => ... 

и при удалении любого из предложений компилятор выдаст предупреждение о неполноте разбора («match nonexhaustive»). Для случаев, когда из множества вариантов лишь некоторые требуют анализа в данном контексте, можно организовать default-ветвление при помощи т. н. «джокера» — универсального образца, с которым сопоставимы все допустимые (согласно типизации) значения. Для его записи используется символ подчёркивания («_»). Например:

fun bar (p:'a foo) = case p of C => ... | _ => ... 

В некоторых языках (в Standard ML, в Haskell) даже «более простая» конструкция if-then-else является лишь синтаксическим сахаром над частным случаем ветвления, то есть выражение

if A then B else C 

уже на этапе грамматического разбора представляется в виде

case A of true => B | false => C 

либо

case A of true => B | _ => C 

Синтаксический сахар

В Standard ML записи и варианты являются мономорфными, однако, поддерживается синтаксический сахар для работы с записями со множеством полей, называемый «универсальным образцом»:

> val r = {name = "Foo", used = true}; (* val r : {name : string, used : bool} = {name = "Foo", used = true} *) > val {used = u, ...} = r; (* val u : bool = true *) 

Многоточие в типе «{used, ...}» означает, что в данной записи существуют и другие поля, помимо упомянутых. Однако полиморфизм записей как таковой отсутствует (даже пренексный): требуется полное статическое разрешение информации о мономорфном типе записи (посредством выведения или явного аннотирования).

Расширение и функциональное обновление записей

Термин расширяемые записи (extensible records) используется для обобщённого обозначения таких операций, как расширение (построение новой записи на основе имеющейся с добавлением новых полей), обрезание (взятие указанной части от имеющейся записи) и др. В частности, он подразумевает возможность так называемого «функционального обновления записей» (functional record update) — операции построения нового значения записи на основе имеющегося путём копирования имён и типов его полей, при которой одно или несколько полей в новой записи получают новые значения, отличающиеся от исходных (и, возможно, имеющие другой тип).

Сами по себе операции функционального обновления и расширения ортогональны полиморфизму записей, но их полиморфное использование представляет особый интерес. Даже для мономорфных записей приобретает большое значение возможность опускать явное упоминание полей, копируемых без изменений, а это фактически представляет собой полиморфизм записей в чисто синтаксической форме. С другой стороны, если рассматривать все записи в системе как расширяемые, то это позволяет типизировать функции над записями как полиморфные.

Пример простейшего варианта конструкции реализован в Alice ML (согласно действующим соглашениям по ). Универсальный образец (многоточие) имеет расширенные возможности: посредством его можно осуществлять «захват ряда» с тем, чтобы работать с «оставшейся» частью записи как со значением:

> val r = {a = 1, b = true, c = "hello"} (* r = {a = 1, b = true, c = "hello"} *) > val {a = n, ... = r1} = r (* r1 = {b=true, c="hello"} *) > val r2 = {d = 3.14, ... = r1} (* r2 = {b=true, c="hello", d=3.14} *) 

Функциональное обновление реализуется как производная форма от захвата ряда с помощью служебного слова where. Например, следующий код:

> let val r = { a = 1, c = 3.0, d = "not a list", f = [1], p = ["not a string"], z = NONE } in { r where d = nil, p = "hello" } end 

будет автоматически переписан в форме:

> let val r = { a = 1, c = 3.0, d = "not a list", f = [1], p = ["not a string"], z = NONE } val { d = _, p = _, ... = tmp } = r in { ... = tmp, d = nil, p = "hello" } end 

Конкатенация записей

Одними из первых (конец 1980-х — начало 1990-х) были предложены различные варианты формализации расширяемых записей через операции конкатенации над неполиморфными записями (Харпер — Пирс, Ванд, Сальцманн). [англ.] даже использовал операции над записями вместо полиморфизма в языке Amber. Для этих исчислений нет известного способа эффективной компиляции; кроме того, эти исчисления весьма сложны и с точки зрения теоретико-ти́пового анализа.

Например:

val car = { name = "Toyota"; age = "old"; id = 6678 } val truck = { name = "Toyota"; id = 19823235 } ... val repaired_truck = { car and truck } 

Ванд (автор рядного полиморфизма) показал, что посредством конкатенации записей можно моделировать множественное наследование.

Структурная подтипизация Карделли

(англ. Luca Cardelli) исследовал возможность формализовать «полиморфизм записей» посредством отношений подтипизации на записях: для этого запись рассматривается как «универсальный подтип», то есть разрешается отнесение её значения ко всему множеству её супертипов. Этот подход также поддерживает наследование методов и служит теоретико-ти́повой базой для наиболее распространённых форм объектно-ориентированного программирования.

Карделли представил вариант метода компиляции полиморфизма записей через их подтипы посредством предопределения смещения всех возможных меток в потенциально огромной структуре со множеством пустых слотов.

Метод имеет существенные недостатки. Поддержка подтипизации в системе типов существенно усложняет механизм проверки согласования типов. Кроме того, в её присутствии статический тип выражения перестаёт предоставлять полную информацию о динамической структуре значения записи. Например, при использовании только подтипов, следующий терм:

> if true then {A = 1, B = true} else {B = false, C = "Cat"} (* val it : {B : bool} *) 

имеет тип {B : bool}, но его динамическое значение равно {A = 1, B = true}, то есть информация о типе расширяемой записи теряется, что представляет серьёзную проблему для проверки операций, требующих для своего исполнения полной информации о структуре значения (таких как сравнение на равенство). Наконец, при наличии подтипов выбор между упорядоченным и неупорядоченным представлением записей серьёзно влияет на производительность.

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

Рядный полиморфизм Ванда

(англ. Mitchell Wand) в 1987 году предложил идею захватывать информацию об «оставшейся» (не указанной явно) части записи посредством того, что он назвал рядной ти́повой переменной (row type variable).

Рядная переменная — это переменная типа, пробегающая множество конечных наборов (рядов) типизированных полей (пар «(значение : тип)»). В результате появляется возможность реализовать «наследование вширину» непосредственно на основе параметрического полиморфизма, лежащего в основе ML,— без усложнения системы типов правилами [англ.]. Получаемую разновидность полиморфизма называют рядным полиморфизмом (row polymorphism). Рядный полиморфизм распространяется как на произведения типов, так и на суммы типов.

Ванд заимствовал термин англ. row (ряд, цепочка, строка) из Алгола-68, где он означал набор представлений. В русскоязычной литературе этот термин в контексте Алгола традиционно переводился как «мультивид». Встречается также вариант перевода «row variables» как «строчные переменные», который может вызвать путаницу со строчными буквами в строковых типах.

Пример (язык OCaml; синтаксис постфиксный, record#field):

# let send_m a = a#m ;; (* value send_m : < m : a; .. > -> a = <fun> *) 

Здесь многоточие (из двух точек) — это принятый в OCaml синтаксис для безымянной рядной ти́повой переменной. За счёт такой типизации, функция send_m может быть применена к объекту любого (заранее не известного) объектного типа, в состав которого входит метод m соответствующей сигнатуры.

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

Наиболее заметный след оставил Дидье́ Реми́ (фр. Didier Rémy). Он построил практичную систему типов с расширяемыми записями, включающую полный и эффективный алгоритм реконструкции типов. Реми расслаивает язык типов на , формулируя сортированную алгебру типов (англ. sorted algebra of types, sorted language of types). Различаются сорт собственно типов (в том числе типов полей) и сорт полей; вводятся отображения между ними и на их основе формулируются правила типизации расширяемых записей как простое расширение классических правил ML. Информация о присутствии (англ. presence) поля определяется как отображение из сорта типов в сорт полей. Рядные ти́повые переменные переформулируются как переменные, принадлежащие сорту полей и равные константе отсутствия (англ. absence), являющейся элементом сорта полей, не имеющим соответствия в сорте типов. Операция вычисления типа для записи из n полей определяется как отображение n-арного поля в тип (где каждое поле в кортеже либо вычисляется функцией присутствия, либо задаётся константой отсутствия).

Упрощённо идею исчисления можно трактовать как расширение типа всякого поля записи флагом присутствия/отсутствия и представление записи в виде кортежа со слотом для каждого возможного поля. В прототипе реализации синтаксис языка типов был сделан приближенным к теоретико-ти́повой формулировке, например:

# let car = { name = "Toyota"; age = "old"; id = 7866 } ;; (* car : ∏ (name : pre (string); id : pre (num); age : pre (string); abs) *) # let truck = { name = "Blazer"; id = 6587867567 } ;; (* truck : ∏ (name : pre (string); id : pre (num); abs) *) # let person = { name = "Tim"; age = 31; id = 5656787 } ;; (* person : ∏ (name : pre (string); id : pre (num); age : pre (num); abs) *) 

(символ у Реми означает операцию вычисления типа)

Добавление нового поля записывается с помощью конструкции with:

# let driver = { person with vehicle = car } ;; (* driver : ∏ (vehicle : pre (∏ (name : pre (string); id : pre (num); age : pre (string); abs));  name : pre (string); id : pre (num); age : pre (num); abs) *) 

Функциональное обновление записывается идентично, с той разницей, что упоминание уже существующего поля переопределяет его:

#let truck_driver = { driver with vehicle = truck };; (* truck driver : ∏ (vehicle : pre (∏ (name : pre (string); id : pre (num); abs));  name : pre (string); id : pre (num); age : pre (num); abs) *) 

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

В дальнейшем Реми исследовал использование рядного полиморфизма совместно с [англ.], подчеркнув, что это ортогональные понятия, и показав, что записи становятся наиболее выразительными при их одновременном использовании. На этой основе он совместно с Жеромом Вуйоном (фр. Jérôme Vouillon) предложил легковесное объектно-ориентированное расширение для ML. Это расширение было реализовано в языке «Caml Special Light» Ксавье Леруа, превратив его в OCaml. Объектная модель OCaml тесно сплетает использование структурной подтипизации и рядного полиморфизма, из-за чего порой их ошибочно отождествляют. Рядный полиморфизм произведений в OCaml лежит в основе выведения типов; отношения подтипизации не являются необходимыми в языке с его поддержкой, но дополнительно повышают гибкость на практике. В OCaml реализован более простой и наглядный синтаксис для информации о типах.

Жак Гарри́га (фр. Jacques Garrigue) реализовал практичную систему полиморфных сумм. Он совместил теоретические работы Реми и Охори, построив систему, пролегающую посередине: информация о наличии меток в записи представляется посредством использования родо́в, а информация об их типах использует рядные переменные. Чтобы компилятор мог отличать полиморфные суммы от мономорфных, Гаррига использует специальный синтаксис (обратный апостроф, предваряющий тег). При этом исчезает необходимость в объявлении типа — можно сразу писать функции над ним, и компилятор будет выводить минимальный список тегов по мере композиции этих функций. Эта система стала частью OCaml около 2000 года, но не вместо, а в дополнение к мономорфным суммам, так как они несколько менее эффективны, и из-за невозможности контроля полноты разбора затрудняют поиск ошибок (в отличие от решения Блюма).

Недостатки рядного полиморфизма Ванда — неочевидность реализации (нет единого систематичного способа его компилировать, каждая конкретная система типов на основе рядных переменных имеет свою реализацию) и неоднозначное соотношение с теорией (нет единообразной формулировки для проверки и выведения типов, поддержка выведения решалась отдельно и потребовала экспериментов с наложением различных ограничений).

Просвечивающие суммы Харпера — Лилибриджа

Наиболее сложной разновидностью записей являются зависимые записи. Такие записи могут включать в себя типы наравне с «обычными» значениями (материализованные типы, реифицированные), причём термы и типы, следующие далее по порядку в теле записи, могут быть определены на основе предшествующих им. Такие записи соответствуют «слабым суммам» из теории зависимых типов, также известным как «экзистенциалы», и служат наиболее общим обоснованием систем модулей языков программирования. [англ.] рассматривал аналогичные по свойствам типы как один из основных типов в полнотиповом программировании (но называл их «кортежами»).

(англ. Robert Harper) и Марк Лилибридж (Mark Lillibridge) построили исчисление просвечивающих сумм (англ. translucent sums) для формального обоснования языка модулей первого класса высшего порядка — наиболее развитой системы модулей среди известных. Это исчисление, в том числе, применяется в семантике Харпера — Стоуна, представляющей теоретико-ти́повое обоснование для Standard ML.

Просвечивающие суммы обобщают слабые суммы за счёт меток и набора равенств, описывающих конструкторы типов. Термин «просвечивающие» (англ. translucent) означает, что в составе типа записи могут присутствовать как типы с явно экспортированной структурой, так и полностью абстрактные. Слой родо́в в исчислении имеет простой классический состав: различаются род всех типов image и функциональные рода́ вида image, типизирующие конструкторы типов (ML не поддерживает полиморфизма в высших рода́х, все переменные типа принадлежат к роду image, и абстракция конструкторов типов возможна лишь посредством функторов). Исчисление различает правила подтипизации для записей как основных типов и для полей записей как их составляющих, соответственно, рассматривая «подтипы» и «подполя», а затемнение (абстрагирование) сигнатур полей является отдельным от подтипизации понятием. Подтипизация здесь формализует сопоставление модулей с интерфейсами.

Исчисление Харпера — Лилибриджа неразрешимо даже в части проверки согласования типов (диалекты языка модулей, реализованные в Standard ML и OCaml, используют ограниченные подмножества этого исчисления). Однако позже Андреас Россберг (англ. Andreas Rossberg) на основе их идей построил язык «1ML», в котором традиционные записи уровня ядра языка и структуры уровня модулей являются одной и той же первоклассной конструкцией (существенно более выразительной, чем у Карделли — см. критика языка модулей ML). За счёт подключения идеи Харпера и Митчела о подразделении всех типов на [англ.] «маленьких» и «больших» типов (упрощённо, это похоже на фундаментальное разделение типов на простые и агрегатные, с неодинаковыми правилами типизации), Россберг обеспечил разрешимость не только проверки согласования, но и почти полного выведения типов. Более того, 1ML допускает импредикативный полиморфизм. При этом внутренний язык в 1ML основан на плоской [англ.] и не требует использования зависимых типов в качестве метатеории. На 2015 год Россберг оставил открытым вопрос о возможности добавления в 1ML рядного полиморфизма, отметив лишь, что это должно обеспечить более полное выведение типов. Спустя год он добавил в 1ML полиморфизм эффектов.

Полиморфное исчисление записей Охори

Ацуси Охори (англ. Atsushi Ohori) совместно со своим научным руководителем (англ. Peter Buneman) в 1988 году предложил идею ограничивать спектр возможных значений обычных типовых переменных в полиморфной типизации самих записей. В дальнейшем Охори формализовал эту идею посредством родо́в записей, построив к 1995 году полноценное исчисление и способ его эффективной компиляции. Прототип реализации был создан в 1992 году как расширение компилятора [англ.], затем Охори возглавил разработку собственного компилятора SML#, реализующего одноимённый диалект языка Standard ML. В SML# полиморфизм записей служит основой для бесшовного встраивания конструкций на SQL в программы на SML. SML# применяется крупными японскими компаниями для решения бизнес-задач, связанных с нагруженными базами данных. Пример такого рода сессии (REPL):

fun wealthy { Salary = s, ... } = s > 100000; (* val wealthy = fn : 'a#{ Salary:int, ... } -> bool *) fun young x = #Age x < 24; (* val young = fn : 'a#{ Age:int, ... } -> bool *) fun youngAndWealthy x = wealthy x andalso young x; (* val youngAndWealthy = fn : 'a#{ Age:int, Salary:int, ... } -> bool *) fun select display l pred = fold (fn (x,y) => if pred x then (display x)::y else y) l nil; (* val select = fn : ('a -> 'b) -> 'a list -> ('a -> bool) -> 'b list *) fun youngAndWealthyEmployees l = select #Name l youngAndWealthy; (* val youngAndWealthyEmployees = fn : 'b#{ Age:int, Name:'a, Salary:int, ... } list -> 'a list *) 

Охори назвал своё исчисление «полиморфизмом записей» (англ. record polymorphism) или «полиморфным исчислением записей» (англ. polymorphic record calculus), одновременно подчеркнув, что он, как и Ванд, рассматривает полиморфизм не только типов-произведений, но и типов-сумм.

Исчисление Охори выделяется наиболее интенсивным использованием слоя родо́в. В записи image (отнесение типа image к роду image) символ image означает либо род всех типов image; либо род записей, имеющих форму image, обозначающий множество всех записей, содержащих как минимум указанные поля; либо род вариантов, имеющих форму image, обозначающий множество всех вариантных типов, содержащих как минимум указанные конструкторы. В плоском синтаксисе языка ограничение типа некоторым родом записи записывается как t#{...} (см. примеры выше). Решение в некоторой степени схоже с [англ.] Карделли — Вегнера.

Единственная полиморфная операция, предусмотренная этим исчислением — операция извлечения поля. Однако Охори был первым, кто представил для полиморфизма записей простую и эффективную схему компиляции. Он назвал её «исчислением реализаций» (implementation calculus). Запись представляется вектором, упорядоченным лексикографически по именам полей исходной записи; обращение к полю по имени транслируется в вызов промежуточной функции, возвращающей номер данного поля в данном векторе по запрашиваемому имени, и последующую индексацию вектора по вычисленному номеру позиции. Функция вызывается только при инстанцировании полиморфных термов, что накладывает минимальный оверхед на рантайм при использовании полиморфизма и не накладывает никакого оверхеда при работе с мономорфными типами. Метод работает одинаково хорошо с произвольно большими записями и вариантами. Исчисление обеспечивает выведение типов и находит строгое соответствие с теорией (родовая квантификация напрямую соотносится с обычной индексацией вектора), представляя собой непосредственно расширение лямбда-исчисление второго порядка Жирара — Рейнольдса, что позволяет переносить различные известные свойства полиморфной типизации на полиморфизм записей.

На практике, поддержка полиморфных вариантов в SML# не была реализована из-за её несовместимости с механизмом определения типов-сумм в Standard ML (требуется синтаксическое разделение сумм и рекурсивных типов).

Недостатком исчисления Охори является отсутствие поддержки операций расширения или обрезания записей.

Первоклассные метки Гастера — Джонса

В теории квалифицированных типов расширяемые записи описываются предикатами отсутствия поля («lacks» predicate) и присутствия поля («has» predicate). Бенедикт Гастер (Benedict R. Gaster) совместно с автором теории Марком Джонсом (Mark P. Jones) доработал её в части расширяемых записей до практичной системы типов неявно типизированных языков, в том числе, определив способ компиляции. Они вводят термин первоклассные метки (first-class labels), подчёркивающий возможность абстрагировать операции над полями от статически известных меток. В дальнейшем Гастер защитил на построенной системе диссертацию.

Исчисление Гастера — Джонса не обеспечивает полное выведение типов. Кроме того, из-за проблем разрешимости было наложено искусственное ограничение: запрет на пустые ряды. Сульцманн предпринял попытку реформулирования исчисления, однако построенная им система не может быть расширена до поддержки полиморфного расширения записей, и не имеет универсального метода эффективной компиляции.

Да́ан Ле́йен (Daan Leijen) добавил в исчисление Гастера — Джонса предикат рядного равенства (или равенства ряда, англ. row equality predicate) и переместил язык рядов в язык предикатов — это обеспечило полное выведение типов и сняло запрет на пустые ряды. При компиляции записи преобразуются в лексикографически упорядоченный кортеж и применяется трансляция свидетельств по схеме Гастера — Джонса. Система Лейена позволяет выражать такие идиомы, как [англ.] (наиболее мощную форму объектно-ориентированного программирования) и первоклассные ветвления.

На основе этих работ реализованы расширения языка Haskell.

Результаты Гастера — Джонса очень близки к результатам Охори, несмотря на существенные различия в теоретико-ти́повом обосновании, и основным преимуществом является поддержка операций расширения и обрезания записей. Недостатком исчисления является то, что оно опирается на свойства системы типов, которые отсутствуют в большинстве языков программирования. Кроме того, выведение типов для него представляет серьёзную проблему, из-за чего авторы наложили дополнительные ограничения. И хотя Лейен устранил многие недостатки, использование default-ветвления невозможно.

Полиморфизм управляющих конструкций

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

Матиас Блюм (англ. Matthias Blume, коллега [англ.], работающий над проектом ), его аспирант Вонсёк Чэй (Wonseok Chae) и коллега Юмат Эйкар (Umut Acar) решили обе проблемы, основываясь на математической двойственности произведений и сумм. Воплощением их идей стал язык MLPolyR, основанный на простейшем подмножестве Standard ML и дополняющий его несколькими уровнями типобезопасности. Позже Вонсёк Чэй защитил на этих достижениях диссертацию.

Решение состоит в следующем. Согласно принципу двойственности, вводная форма (англ. introduction form) для некоего понятия соответствует устраняющей форме (англ. elimination form) двойственного ему. Таким образом, устраняющая форма сумм (разбор ветвлений) соответствует вводной форме записей. Это побуждает наделить ветвления теми же свойствами, что уже доступны для записей — сделать их первоклассными объектами и допустить их расширение.

Например, простейший интерпретатор языка выражений:

fun eval e = case e of `Const i => i | `Plus (e1,e2) => eval e1 + eval e2 

с введением первоклассной конструкции cases может быть переписан в виде:

fun eval e = match e with cases `Const i => i | `Plus (e1,e2) => eval e1 + eval e2 

после чего cases-блок может быть вынесен:

fun eval_c eval = cases `Const i => i | `Plus (e1,e2) => eval e1 + eval e2 fun eval e = match e with (eval_c eval) 

Это решение допускает default-ветвления (в отличие от исчисления Гастера — Джонса), что важно для композиции первоклассных ветвлений. Завершение композиции ряда осуществляется с помощью слова nocases.

fun const_c d = cases `Const i => i default: d fun plus_c eval d = cases `Plus (e1,e2) => eval e1 + eval e2 default: d fun eval e = match e with const_c (plus_c eval nocases) fun bind env v1 x v2 = if v1 = v2 then x else env v2 fun var_c env d = cases `Var v => env v default: d fun let_c eval env d = cases `Let (v,e,b) => eval (bind env v (eval env e)) b default: d fun eval_var env e = match e with const_c (plus_c (eval_var env) (var_c env (let_c eval_var env nocases))) 

Как видно, новый код, который необходимо дописывать при качественном усложнении системы, не требует изменения уже написанного кода (функции const_c и plus_c «ничего не знают» о последующем добавлении в интерпретатор языка поддержки переменных и let-блоков). Таким образом, первоклассные расширяемые ветвления (first-class extensible cases) являются принципиальным решением [англ.], позволяя говорить о парадигме расширяемого программирования. По словам Блюма, это является не чем-то принципиально новым, а просто интересным способом применения рядного полиморфизма, который уже поддерживается в системе типов, и в этом смысле достоинством такого технического решения является его концептуальная простота.

Однако расширение программных систем требует также контроля над обработкой исключений, которые могут порождаться на произвольной глубине вложения вызовов. И здесь Блюм с коллегами провозглашают новый слоган типобезопасности в развитие слогана Милнера: «Программы, прошедшие проверку типов, не порождают необработанных исключений». Проблема состоит в том, что если сигнатура функционального типа включает информацию о типах исключений, которые эта функция потенциально может порождать, и эта информация в сигнатуре передаваемой функции должна быть строго согласована с информацией о параметре функции высшего порядка (в том числе, если это пустое множество) — типизация механизма обработки исключений немедленно требует полиморфности типов самих исключений — в противном случае функции высшего порядка перестают быть полиморфными. В то же время, в безопасном языке исключения являются расширяемой суммой, то есть вариантным типом, конструкторы которого добавляются по ходу программы. Соответственно, типобезопасность потока исключений означает необходимость поддержки типов-сумм, которые являются одновременно расширяемыми и полиморфными. И здесь вновь решением является рядный полиморфизм.

Как и в исчислении Гарриги, для полиморфных сумм в MLPolyR используется специальный синтаксис (обратный апостроф, предваряющий тег), и нет нужды в предварительном объявлении типа-суммы (то есть вышеприведённый код — это вся программа, а не фрагмент). Преимущество состоит в том, что проблемы с контролем полноты разбора не возникает: семантика MLPolyR определена через преобразование во внутренний язык с доказанной надёжностью, не поддерживающий ни полиморфизма сумм, ни исключений (не говоря уже о непойманных исключениях), так что необходимость их удаления на этапе компиляции сама по себе является доказательством надёжности.

MLPolyR использует нетривиальное сочетание нескольких исчислений и двухстадийную трансляцию. Для выведения и согласования типов он использует исчисление Реми, одновременно используя принцип математической двойственности для представления сумм как произведений, далее транслирует язык в промежуточный явно типизированный язык с полиморфными записями, и затем использует эффективный способ компиляции, построенный Охори. Иначе говоря, модель компиляции Охори была обобщена до поддержки исчисления Реми. На теоретико-ти́повом уровне Блюм вводит сразу несколько новых синтаксических нотаций, позволяющих записывать правила для типизации исключений и первоклассных ветвлений. Система типов MLPolyR обеспечивает полное выведение типов, так что авторы отказались от разработки плоского синтаксиса для явной записи типов и от поддержки сигнатур в языке модулей.

В системе типов Лейена также возникает вариант полиморфизма ветвлений: конструкция case может быть представлена в виде функции высшего порядка, получающей запись из функций, каждая из которых соответствует определённой ветви вычислений (синтаксис Хаскела подходит для этого изменения и не требует пересмотра). Например:

data List a = nil :: {}  | cons :: { hd :: a, tl :: List a } snoc xs r = case (reverse xs) r last xs = snoc xs { nil = \r -> _|_,  cons = \r -> r.hd } 

Поскольку записи в системе Лейена являются расширяемыми, разбор ветвлений обретает гибкость на уровне динамических решений (например, цепочки проверок или использования ассоциативного массива), но обеспечивает гораздо более эффективную реализацию (метка варианта соответствует смещению в записи). Однако, от поддержки ветвления по умолчанию (default) в данном случае приходится отказаться, поскольку единственный default-образец соответствовал бы множеству полей (и, соответственно, множеству смещений). Лейен называет эту конструкцию «первоклассными образцами для сопоставления» (first-class patterns).

Полиморфизм в высших рода́х

Полиморфизм в высших рода́х (англ. higher-kinded polymorphism) означает абстракцию над конструкторами типов высших порядков, то есть ти́повыми операторами вида

* -> * -> ... -> *

Поддержка этой возможности поднимает полиморфизм на более высокий уровень, обеспечивая абстракцию как над типами, так и над конструкторами типов — подобно тому как функции высших порядков обеспечивают абстракцию как над значениями, так и над другими функциями. Полиморфизм в высших рода́х является естественным компонентом многих идиом функционального программирования, включая монады, свёртки и встраиваемые языки.

Например, если определить следующую функцию (язык Haskell):

when b m = if b then m else return () 

то для неё будет выведен такой функциональный тип:

when :: forall (m :: * -> *). Monad m => Bool -> m () -> m () 

Сигнатура m :: * -> * говорит о том, ти́повая переменная m является переменной типа, принадлежащего к высшему роду (англ. higher-kinded type variable). Это значит, что она абстрагируется над конструкторами типов (в данном случае унарными, такими как Maybe или []), которые могут применяться к конкретным типам, таким как Int или (), для построения новых типов.

В языках, поддерживающих полную абстракцию типа (Standard ML, OCaml), все ти́повые переменные должны принадлежать к роду *, в противном случае система типов была бы небезопасной. Полиморфизм в высших рода́х, таким образом, обеспечивается за счёт самого механизма абстракции в сочетании с явным аннотированием при инстанцировании, что несколько неудобно. Тем не менее, возможна идиоматическая реализация полиморфизма в высших рода́х, не требующая явного аннотирования — для этого на уровне типов применяется техника, аналогичная дефункционализации.

Полиморфизм родо́в

Системы родо́в (англ. kind systems) обеспечивают безопасность самих систем типов, позволяя контролировать смысл ти́повых выражений.

Например, пусть требуется реализовать вместо обычного типа «вектор» (линейный массив) семейство типов «вектор длиной n», иначе говоря, определить тип «вектор, индексированный длиной». Классическая реализация на Haskell выглядит так:

data Zero data Succ n data Vec :: * -> * -> * where  Nil :: Vec a Zero  Cons :: a -> Vec a n -> Vec a (Succ n) 

Здесь вначале определяются фантомные типы, то есть типы, не имеющие динамического представления. Конструкторы Zero и Succ служат «значениями слоя типов», а переменная n обеспечивает неравенство разных конкретных типов, построенных конструктором Succ. Тип Vec определён как обобщённый алгебраический тип данных (GADT).

Решение условно предполагает, что фантомный тип n будет использоваться для моделирования целочисленного параметра вектора на основе аксиом Пеано — то есть будут строиться только такие выражения, как Succ Zero, Succ Succ Zero, Succ Succ Succ Zero и т. д. Однако, хотя определения записаны на языке типов, сами по себе они сформулированы бестиповым образом. Это видно по сигнатуре Vec :: * -> * -> *, означающей, что конкретные типы, передаваемые в качестве параметров, принадлежат роду *, а значит, могут быть любым конкретным типом. Иначе говоря, здесь не запрещаются бессмысленные ти́повые выражения вроде Succ Bool или Vec Zero Int.

Более развитое исчисление позволило бы задать область значений параметра типа более точно:

data Nat = Zero | Succ Nat data Vec :: * -> Nat -> * where  VNil :: Vec a Zero  VCons :: a -> Vec a n -> Vec a (Succ n) 

Но обычно такой выразительностью обладают лишь узко-специализированные системы с зависимыми типами, реализованные в таких языках, как Agda, Coq и другими. Например, с позиции языка Agda запись Vec :: * -> Nat -> * означала бы, что род типа Vec зависит от типа Nat (то есть элемент одного зависит от элемента другого, более низкого ).

В 2012 году было построено расширение языка Haskell, реализующее более развитую систему родо́в и делающее вышеприведённый код корректным кодом на Haskell. Решение состоит в том, что все типы (за определёнными ограничениями) автоматически «продвигаются» (англ. promote) на уровень выше, формируя одноимённые рода́, которые можно использовать явным образом. С этой точки зрения, запись Vec :: * -> Nat -> * не является зависимой — она означает лишь, что второй параметр вектора должен принадлежать к именованному роду Nat, а в данном случае единственным элементом этого рода является одноимённый тип.

Решение является весьма простым, как с точки зрения реализации в компиляторе, так и с точки зрения практической доступности. А поскольку полиморфизм типов изначально является естественным элементом семантики Haskell, продвижение типов приводит к полиморфизму родо́в (англ. kind polymorphism), который одновременно повышает коэффициент повторного использования кода и обеспечивает более высокий уровень типобезопасности. Например, следующий GADT, используемый для верификации равенства типов:

data EqRefl a b where  Refl :: EqRefl a a 

в классическом Haskell имеет род * -> * -> *, что не позволяет использовать его для проверки равенства конструкторов типов, таких как Maybe. Система родов, основанная на продвижении типов, выводит полиморфный род forall X. X -> X -> *, делая тип EqRefl более универсальным. Это можно записать явно:

data EqRefl (a :: X) (b :: X) where  Refl :: forall X. forall(a :: X). EqRefl a a 

Полиморфизм эффектов

Системы эффектов (англ. effect systems) были предложены Гиффордом и Лукассеном во второй половине 1980-х с целью обособления побочных эффектов для более тонкого контроля за безопасностью и эффективностью в конкурентном программировании.

Полиморфизм эффектов (англ. effect polymorphism) при этом означает квантификацию над чистотой конкретной функции, то есть включение в функциональный тип флага, характеризующего функцию как чистую либо нечистую. Такое расширение типизации позволяет абстрагировать чистоту функций высшего порядка от чистоты функций, передаваемых им в качестве аргументов.

Это приобретает особое значение при переходе к функциям над модулями (записями, включающими в свой состав абстрактные типы) — функторам — поскольку в условиях чистоты они имеют право быть аппликативными, но в присутствии побочных эффектов они обязаны быть порождающими для обеспечения типобезопасности (подробнее об этом см. эквивалентность типов в языке модулей ML). Таким образом, в языке модулей первого класса высшего порядка полиморфизм эффектов оказывается необходимой основой для поддержки полиморфизма порождаемости (англ. generativity polymorphism): передача флага чистоты в функтор обеспечивает выбор между аппликативной и порождающей семантикой в единой системе.

Поддержка в языках программирования

Типобезопасный параметрический полиморфизм доступен в языках, типизированных по Хиндли — Милнеру — в диалектах ML (Standard ML, OCaml, Alice, F#) и их потомках (Haskell, Clean, Idris, Mercury, Agda) — а также в наследованных от них гибридных языках (Scala, Nemerle).

Обобщённые типы данных (дженерики) отличаются от параметрически полиморфных систем тем, что используют [англ.], и потому не могут иметь ранг выше 1-го. Они доступны в Ada, Eiffel, Java, C#, D, Rust; а также в Delphi, начиная с 2009-й версии. Впервые они появились в CLU.

Интенсиональный полиморфизм

Интенсиональный полиморфизм (англ. intensional polymorphism) представляет собой технику оптимизирующей компиляции параметрического полиморфизма на основе сложного теоретико-ти́пового анализа, которая состоит в вычислениях над типами во время выполнения программы. Интенсиональный полиморфизм позволяет реализовывать бестеговую сборку мусора, необёрнутую (unboxed) передачу аргументов в функции и упакованные (оптимизированные по памяти) плоские структуры данных.

Мономорфизация

Мономорфизация (англ. monomorphizing) представляет собой технику оптимизирующей компиляции параметрического полиморфизма, которая заключается в порождении мономорфного экземпляра для каждого случая использования полиморфной функции или типа. Другими словами, параметрический полиморфизм на уровне исходного кода транслируется в ad hoc полиморфизм на уровне целевой платформы. Мономорфизация повышает быстродействие (точнее, делает полиморфизм «бесплатным»), но вместе с тем может увеличивать размер выходного машинного кода.

Хиндли — Милнер

В классическом варианте система типов Хиндли — Милнера (а также просто «Хиндли — Милнер» или «Х-М», англ. HM), положенная в основу языка ML, представляет собой подмножество Системы F, ограниченное предикативным пренексным полиморфизмом с целью обеспечения возможности автоматического выведения типов, для чего в состав Хиндли — Милнера традиционно также включался так называемый «[англ.]», разработанный Робином Милнером.

Многие реализации Х-М являются улучшенной версией системы, представляя собой «систему главной типизации» (англ. principal typing scheme), которая за один проход с почти линейной сложностью одновременно выводит наиболее общие полиморфные типы для каждого выражения и строго проверяет их согласование.

С момента своего появления система типов Хиндли — Милнера была расширена по нескольким направлениям. Одним из наиболее известных расширений является поддержка ad-hoc-полиморфизма посредством классов типов, дальнейшим обобщением которых стали квалифицированные типы.

Автоматическое выведение типов было сочтено необходимостью при первоначальной разработке языка ML в качестве интерактивной системы доказательства теорем «Logic for Computable Functions», из-за чего и были наложены соответствующие ограничения. В дальнейшем на основе ML был разработан целый ряд эффективно компилируемых языков общего назначения, ориентированных на [англ.], а в этом случае необходимость поддержки выведения типов резко снижается, так как интерфейсы модулей в промышленной практике в любом случае необходимо явно аннотировать типами. Поэтому было предложено множество вариантов расширения Хиндли — Милнера, отказывающихся от выведения типов ради расширения возможностей, вплоть до поддержки полной Системы F с импредикативным полиморфизмом, таких как язык модулей высшего порядка, изначально основанный на явном аннотировании типов модулей и имеющий множество расширений и диалектов, а также расширения языка Haskell (Rank2Types, RankNTypes и ImpredicativeTypes).

Компилятор MLton языка Standard ML осуществляет мономорфизацию, но за счёт других применимых к Standard ML оптимизаций результирующее увеличение выходного кода не превышает 30 %.

Си и C++

В языке Си функции не являются объектами первого класса, но возможно определение указателей на функции, что позволяет строить функции высших порядков. Также доступен небезопасный параметрический полиморфизм за счёт явной передачи необходимых свойств типа через бестиповое подмножество языка, представленное нетипизированным указателем void* (называемым в сообществе языка «обобщённым указателем» (англ. generic pointer). Назначение и удаление информации о типе при приведении типа к void* и обратно не является ad-hoc-полиморфизмом, так как не меняет представление указателя, однако, его записывают явно для обхода системы типов компилятора.

Например, стандартная функция qsort способна обрабатывать массивы элементов любого типа, для которого определена функция сравнения.

struct segment { int start; int end; }; int seg_cmpr( struct segment *a, struct segment *b ) { return abs( a->end - a->start ) - abs( b->end - b->start ); } int str_cmpr( char **a, char **b ) { return strcmp( *a, *b ); } struct segment segs[] = { {2,5}, {4,3}, {9,3}, {6,8} }; char* strs[] = { "three", "one", "two", "five", "four" }; main() {  qsort( strs, sizeof(strs)/sizeof(char*), sizeof(char*),  (int (*)(void*,void*))str_cmpr );  qsort( segs, sizeof(segs)/sizeof(struct segment), sizeof(struct segment),  (int (*)(void*,void*))seg_cmpr );  ... } 

Тем не менее, в Си возможно идиоматическое воспроизведение типизированного параметрического полиморфизма без использования void*.

Язык C++ предоставляет подсистему шаблонов, использование которых внешне похоже на параметрический полиморфизм, но семантически реализуется сочетанием ad hoc-механизмов:

template <typename T> T max(T x, T y) {  if (x < y)  return y;  else  return x; } int main() {  int a = max(10,15);  double f = max(123.11, 123.12);  ... } 

Мономорфизация при компиляции шаблонов C++ является неизбежной, так как в системе типов языка отсутствует поддержка полиморфизма — полиморфный язык здесь является [англ.] надстройкой над мономорфным ядром языка. Это приводит к кратному увеличению объёма получаемого машинного кода, что получило известность как «раздувание кода».

История

Нотацию параметрического полиморфизма как развитие лямбда-исчисления (названную полиморфным лямбда-исчислением или Системой F) формально описал логик [англ.] (1971 год), независимо от него похожую систему описал информатик [англ.] (1974 год).

Впервые параметрический полиморфизм был представлен в языке ML в 1973. Независимо от него параметрические типы были реализованы под руководством Барбары Лисков в CLU (1974 год).

См. также

  • Конструктор типов
  • Род (теория типов)
  • [англ.]

Примечания

  1. Strachey, "Fundamental Concepts", 1967.
  2. Пирс, 2002.
  3. Cardelli, Wegner, "On Understanding Types", 1985, 1.3. Kinds of Polymorphism, с. 6.
  4. Appel, "Critique of SML", 1992.
  5. Jones, "Theory of Qualified Types", 1992.
  6. Gaster, Jones, "Polymorphic Extensible Records and Variants", 1996.
  7. Cardelli, "Basic Polymorphic Typechecking", 1987.
  8. Wonseok Chae (Ph.D. Thesis), 2009, с. 91—92.
  9. Rossberg, "1ML – Core and Modules United (F-ing First-class Modules)", 2015.
  10. Blume, "Exception Handlers", 2008, с. 11.
  11. Wells, 1994.
  12. Пирс, 2002, 22 Реконструкция типов, с. 361.
  13. Пирс, 2002, 23.6 Стирание, типизируемость и реконструкция типов, с. 378—381.
  14. Remy, "ML with abstract and record types", 1994.
  15. Garrigue, Remy, "Semi-Explicit First-Class Polymorphism for ML", 1997.
  16. Reynolds, "Theories of programming languages", 1998, 17. Polymorphism. Bibliographic Notes, с. 393.
  17. First-class polymorphism on MLton. Дата обращения: 28 июля 2016. Архивировано 28 ноября 2015 года.
  18. Пирс, 2002, 22.7 Полиморфизм через let, с. 354—359.
  19. Ohori, "Polymorphic Record Calculus and Its Compilation", 1995.
  20. Душкин, "Мономорфизм, полиморфизм и экзистенциальные типы", 2010.
  21. Cardelli, "Typeful programming", 1991, с. 20.
  22. Пирс, 2002, 23.10 Импредикативность, с. 385.
  23. Пирс, 2002, Глава 22. Реконструкция типов. Раздел 22.8. Дополнительные замечания, с. 361—362.
  24. Wonseok Chae (Ph.D. Thesis), 2009, с. 14.
  25. Garrigue, "Polymorphic Variants", 1998.
  26. Blume, "Extensible Programming with First-Class Cases", 2006, с. 10.
  27. Ohori, "Polymorphic Record Calculus and Its Compilation", 1995, 1.1 Static Type System for Record Polymorphism, с. 3—6.
  28. Leijen, "First-class Labels", 2004, с. 1.
  29. Gaster, Jones, "Polymorphic Extensible Records and Variants", 1996, Abstract, с. 1.
  30. Paulson, "ML for the Working Programmer", 1996, 2.9 Records, с. 35.
  31. Ohori, "Polymorphic Record Calculus and Its Compilation", 1995, 1.2 Compilation Method for Record Polymorphism, с. 6—8.
  32. Harper, "Intro to SML", 1986.
  33. Remy, "Type Inference for Records", 1991, с. 2.
  34. Blume, "Row polymorphism at work", 2007.
  35. Functional record update. Дата обращения: 30 июня 2016. Архивировано 2 июня 2016 года.
  36. Alice ML syntactic enhancements. Дата обращения: 30 июня 2016. Архивировано 27 ноября 2016 года.
  37. Functional record extension and row capture. Дата обращения: 30 июня 2016. Архивировано 13 августа 2016 года.
  38. Harper, Pierce, "Record calculus based on symmetric concatenation", 1991.
  39. Wand, "Type inference for record concatenation and multiple inheritance", 1991.
  40. Sulzmann, 1997.
  41. Пирс, 2002, 1.4 Краткая история, с. 11—13.
  42. Remy, "Type Inference for Records", 1991, с. 2—3.
  43. Leijen, "First-class Labels", 2004, с. 13—14.
  44. Cardelli, "Semantics of Multiple Inheritance", 1988.
  45. Cardelli, Wegner, "On Understanding Types", 1985.
  46. Пирс, 2002, 16. Метатеория подтипов, с. 225.
  47. Пирс, 2002, 11.8 Записи, с. 135.
  48. Мински в переводе ДМК, 2014, Подтипизация и рядный полиморфизм, с. 267—268.
  49. Wand, "Type inference for objects", 1987.
  50. Мински в переводе ДМК, 2014, Полиморфизм объектов, с. 255—257.
  51. Remy, "Type Inference for Records", 1991, Related work, с. 3.
  52. Remy, "Type Inference for Records", 1991.
  53. Blume, "Extensible Programming with First-Class Cases", 2006, с. 11.
  54. Remy, "Subtypes and Row polymorphism", 1995.
  55. Remy, Vouillon, "Objective ML", 1998.
  56. Пирс, 2002, 15.8 Дополнительные замечания, с. 223.
  57. Мински в переводе ДМК, 2014, Полиморфные варианты, с. 149—158.
  58. Пирс, 2002, 24 Экзистенциальные типы, p. 404.
  59. Reynolds, "Theories of programming languages", 1998, 18. Module Specification, с. 401—410.
  60. Cardelli, "Typeful programming", 1991, 4.4. Tuple types, с. 20—23.
  61. Harper, Lillibridge, "Type-Theoretic Approach to Higher-Order Modules with Sharing", 1993.
  62. Yallop, White, "Lightweight higher-kinded polymorphism", 2014.
  63. Harper, Mitchell, "Type Structure of SML", 1993.
  64. Rossberg, "1ML – Core and Modules United (F-ing First-class Modules)", 2015, Impredicativity Reloaded, с. 6.
  65. Rossberg, "1ML with Special Effects (F-ing Generativity Polymorphism)", 2016.
  66. Ohori, "Compilation Method for Polymorphic Record Calculi", 1992.
  67. Ohori — SML# (presentation). Дата обращения: 30 июня 2016. Архивировано из оригинала 27 августа 2016 года.
  68. Ohori, "Polymorphic Record Calculus and Its Compilation", 1995, с. 38.
  69. Blume, "Extensible Programming with First-Class Cases", 2006, с. 9.
  70. Ohori, "Polymorphic Record Calculus and Its Compilation", 1995, 5 Implementaion, с. 37.
  71. Blume, "Extensible Programming with First-Class Cases", 2006.
  72. Gaster (Ph.D. Thesis), 1998.
  73. Leijen, "First-class Labels", 2004, с. 7.
  74. Leijen, "First-class Labels", 2004.
  75. Extensible records on Haskell-Wiki (недоступная ссылка)
  76. Blume personal page. Дата обращения: 30 июня 2016. Архивировано 19 мая 2016 года.
  77. Blume, "Exception Handlers", 2008.
  78. Wonseok Chae (Ph.D. Thesis), 2009.
  79. Paulson, "ML for the Working Programmer", 1996, 4.6 Declaring exceptions, с. 135.
  80. Harper, "Practical Foundations for Programming Languages", 2012, 28.3 Exception Type, с. 258—260.
  81. ML2000 Preliminary Design, 1999.
  82. Harper, "Practical Foundations for Programming Languages", 2012, Chapter 22. Constructors and Kinds, с. 193.
  83. Weirich et al, "Giving Haskell a promotion", 2012.
  84. Fluet, Pucella, "Phantom Types and Subtyping", 2006.
  85. Пирс, 2002, 30.5 Идем дальше: зависимые типы, с. 489—490.
  86. Gifford, Lucassen, "Effect systems", 1986.
  87. Lucassen, Gifford, "Polymorphic Effect Systems", 1988.
  88. Talpin, Jouvelot, 1992.
  89. Harper, Morrisett, "Intensional Type Analysis", 1995.
  90. Crary, Weirich, Morrisett, "Intensional polymorphism", 1998.
  91. Пирс, 2002, 23.2 Разновидности полиморфизма, с. 364—365.
  92. Weeks, "Whole-Program Compilation in MLton", 2006.
  93. Hindley, "Principal Type Scheme", 1969.
  94. Milner, "Theory of Type Polymorphism", 1978.
  95. Jones, "FP with Overloading and H-O Polymorphism", 1995.
  96. Керниган Б., Ритчи Д. Язык программирования Си = The C programming language. — 2-е изд. — , 2007. — С. 304. — ISBN 0-13-110362-8., Глава 5.11. Указатели на функции
  97. Appel, "Critique of SML", 1992, с. 5.
  98. Oleg Kiselyov. Truly polymorphic lists in C. okmij.org. Дата обращения: 22 ноября 2016. Архивировано 30 января 2017 года.
  99. Mitchell, "Concepts in Programming Languages", 2004, 6.4. Polymorphism and overloading, с. 145—151.
  100. Scott Meyers. Code Bloat due to Templates. comp.lang.c++.moderated. Usenet (16 мая 2002). Дата обращения: 19 января 2010.
  101. Girard, "Extension of Type Theory", 1971.
  102. Girard, "Higher-order calculus", 1972.
  103. Reynolds, "Theory of Type Structure", 1974.
  104. Пирс, 2002, 23.3 Система F, с. 365—366.
  105. Milner et al, "LCF", 1975.

Литература

  • Christopher Strachey. Fundamental Concepts in Programming Languages. — 1967. Архивировано 12 августа 2017 года.
    • Повторно опубликовано: Christopher Strachey. Fundamental Concepts in Programming Languages // . — 2000. — Т. 13. — С. 11—49. — doi:10.1023/A:1010000313106.
  • J. Roger Hindley. The principal type scheme of an object in combinatory logic (англ.) // Transactions of the American Mathematical Society. — American Mathematical Society, 1969. — Vol. 146. — P. 29—60. — doi:10.2307/1995158.
  • Jean-Yves Girard. Une Extension de l'Interpretation de Gödel à l'Analyse, et son Application à l'Élimination des Coupures dans l'Analyse et la Théorie des Types (фр.) // Proceedings of the Second Scandinavian Logic Symposium. — Amsterdam, 1971. — P. 63—92. — doi:10.1016/S0049-237X(08)70843-7.
  • Jean-Yves Girard. Interprétation fonctionnelle et élimination des coupures de l’arithmétique d’ordre supérieur (фр.). — Université Paris 7, 1972.
  • John C. Reynolds. Towards a Theory of Type Structure // . — Paris: Colloque sur la programmation, 1974. — Т. 19. — С. 408—425. — doi:10.1007/3-540-06859-7_148.
  • Milner R., Morris L., Newey M. A Logic for Computable Functions with reflexive and polymorphic types // Arc-et-Senans. — Proc. Conference on Proving and Improving Programs, 1975.
  • Robin Milner. A Theory of Type Polymorphism in Programming. — [англ.], 1978. — Т. 17, вып. 3. — С. 348—375. — doi:10.1016/0022-0000(78)90014-4.
  • [англ.], John С. Mitchell. Operations on Records // Mathematical Structures in Computer Science. — 1991. — Т. 1, вып. 1.
  • [англ.], Peter Wegner. On Understanding Types, Data Abstraction, and Polymorphism // . — New York, USA: ACM, 1985. — Т. 17, вып. 4. — С. 471—523. — ISSN 0360-0300. — doi:10.1145/6041.6042.
  • [англ.]. Введение в Стандартный ML. — Carnegie Mellon University, 1986. — 97 с. — ISBN PA 15213-3891.
  • John M. Lucassen, David K. Gifford. Integrating Functional and Imperative Programming. — 1986.
  • [англ.]. Basic Polymorphic Typechecking. — 1987.
  • [англ.]. Complete Type Inference for Simple Objects (англ.) // In Proc. 2nd IEEE Symposium on Logic in Computer Science. — 1987. — P. 37—44.
  • Martín Abadi, [англ.], Pierre-Louis Curien. Formal Parametric Polymorphism. — POPL, 1993.
  • [англ.]. A Semantics of Multiple Inheritance (англ.) // Inf. Comput. 76. — 1988. — P. 138—164.
  • John M. Lucassen, David K. Gifford. Polymorphic Effect Systems. — , 1988.
  • Didier Rémy. Type Inference for Records in a natural Extension of ML // Research Report 1431. — Institut National de Recherche en Informatique et Automatisme, 1991.
  • [англ.]. Typeful programming (англ.) // IFIP State-of-the-Art Reports. — New York: Springer-Verlag, 1991. — Iss. Formal Description of Programming Concepts. — P. 431—507.
  • [англ.], Benjamin Pierce. Record calculus based on symmetric concatenation // CMU-CS-90-157R. — Carnegie Mellon University, supported and monitored by Naval Research, 1991.
  • [англ.]. Type inference for record concatenation and multiple inheritance // Selections from 1989 IEEE Symposium on Logic in Computer Science. — Information and Computation,, 1991. — Т. 93, вып. 1. — doi:10.1016/0890-5401(91)90050-C.
  • Andrew W. Appel. A Critique of Standard ML. — Princeton University, 1992.
  • Mark P. Jones. A Theory of Qualified Types. — ESOP, Springer-Verlag Lecture Notes in Computer Science, 1992.
  • Atsushi Ohori. A Compilation Method for ML-Style Polymorphic Record Calculi // POPL: Proceedings of the 19th ACM SIGPLAN-SIGACT symposium on Principles of programming languages,. — Kyoto University, ACM, 1992. — С. 154—165. — doi:10.1.1.105.7655.
  • J.-P. Talpin, P. Jouvelot. Polymorphic Type, Region and Effect Inference // 2(3):245271. — , 1992.
  • [англ.], John С. Mitchell. On The Type Structure of Standard ML. — ACM TOPLAS, 1993. — С. 211—252.
  • [англ.], Mark Lillibridge. Type-Theoretic Approach to Higher-Order Modules with Sharing (англ.). — ACM Press, , 1993. — ISBN CMU-CS-93-197. — doi:10.1.1.14.3595.
  • Didier Rémy. Programming objects with ML-ART: An extension to ML with abstract and record types. — International Symposium on Theoretical Aspects of Computer Software, Springer-Verlag, 1994. — С. 321—346.
  • J. B. Wells. Typability and Type Checking in the Second-Order Lambda-Calculus are Equivalent and Undecidable (англ.) // Proceedings of the 9th Annual IEEE. — Symposium on Logic in Computer Science (LICS), 1994. — P. 176—185.
  • [англ.], . Compiling Polymorphism Using Intensional Type Analysis. — 1995.
  • Atsushi Ohori. A Polymorphic Record Calculus and Its Compilation. — Kyoto University, ACM, 1995. — С. 844—895.
  • Mark P. Jones. Functional Programming with Overloading and Higher-Order Polymorphism. — Springer-Verlag Lecture Notes, 1995. — doi:10.1.1.26.9460.
  • Didier Rémy. Better Subtypes and Row Variables for Record Types // Presented at the workshop on Advances in types for computer science at the Newton Institute. — Cambridge, UK, 1995.
  • [англ.]. ML for the Working Programmer. — 2nd. — Cambridge, Great Britain: Cambridge University Press, 1996. — 492 с. — ISBN 0-521-57050-6 (hardback), 0-521-56543-X (paperback).
  • Benedict R. Gaster, Mark P. Jones. A Polymorphic Type System for Extensible Records and Variants // Technical Report NOTTCS-TR-96-3. — University of Nottingham, 1996.
  • Jacques Garrigue, Didier Rémy. Semi-Explicit First-Class Polymorphism for ML // Academic Press. — Information and Computation, 1997.
  • M. Sulzmann. Designing Record Systems // Technical Report YALEU/DCS/RR-1128. — Yale University, 1997. — doi:10.1.1.17.6563.
  • Karl Crary, Stephanie Weirich, J. Gregory Morrisett. Intensional polymorphism in type-erasure semantics. — , 1998.
  • Benedict R. Gaster. Records, variants and qualified types // Technical report NOTTCS-TR-98-3. — Ph.D. Thesis, 1998.
  • Jacques Garrigue. Programming with Polymorphic Variants. — Kyoto University, 1998.
  • Didier Rémy, Jérôme Vouillon. Objective ML: An effective object-oriented extension to ML. — Theory And Practice of Object Systems, ACM, 1998. — Т. 4(1). — С. 27—50.
  • John C. Reynolds. Theories of programming languages. — Cambridge University Press, 1998. — ISBN 978-0-521-59414-1 (hardback), 978-0-521-10697-9 (paperback).
  • The ML2000 Working Group. Principles and a Preliminary Design for ML2000 (англ.). — 1999.
  • Benjamin Pierce. Types and Programming Languages. — MIT Press, 2002. — ISBN 0-262-16209-1.
    • Перевод на русский язык: Бенджамин Пирс. Типы в языках программирования. — , 2012. — 680 с. — ISBN 978-5-7913-0082-9.
  • John C. Mitchell. Concepts in Programming Languages. — Cambridge University Press, 2004. — ISBN 0-511-04091-1 (eBook in netLibrary); 0-521-78098-5 (hardback).
  • Jens Palsberg, Tian Zhao. Type Inference for Record Concatenation and Subtyping. — 2004. Архивировано 16 сентября 2016 года.
  • Daan Leijen. First-class Labels for Extensible Rows // TechReport UU-CS-2004-51. — Universiteit Utrecht, 2004.
  • Matthias Blume, Umut A. Acar, Wonseok Chae. Extensible Programming with First-Class Cases. — , 2006.
  • Matthew Fluet, Riccardo Pucella. Phantom Types and Subtyping (англ.). — , 2006.
  • Stephen Weeks. Whole-Program Compilation in MLton (англ.). — 2006. Архивировано 29 июня 2007 года.
  • Matthias Blume. Records, Sums, Cases and Exceptions: Row polymorphism at work : speech video. — Microsoft, 2007.
  • Matthias Blume, Umut A. Acar, Wonseok Chae. Exception Handlers as Extensible Cases. — Toyota Technological Institute at Chicago, APLAS, 2008.
  • Wonseok Chae. Type Safe Extensible Programming // Ph.D. Thesis. — Toyota Technological Institute at Chicago, 2009.
  • Роман Душкин. Мономорфизм, полиморфизм и экзистенциальные типы. — 2010.
  • Jeremy Yallop, Leo White. Lightweight higher-kinded polymorphism. — International Symposium on Functional and Logic Programming, 2014.
  • [англ.]. Practical Foundations for Programming Languages. — version 1.37 (revised 01.11.2014). — licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License., 2012. — 544 с. Архивная копия от 24 октября 2015 на Wayback Machine
  • Stephanie Weirich, Brent A. Yorgey, Julien Cretin, Simon Peyton Jones, Dimitrios Vytiniotis, and Jose P. Magalhães. Giving Haskell a promotion // In Proceedings of the 8th ACM SIGPLAN Workshop on Types in Language Design and Implementation. — NY, USA: , 2012. — С. 53—66.
  • Minsky, Madhavapeddy, Hickey. Real World OCaml: Functional Programming for the Masses (англ.). — O'Reilly Media, 2013. — 510 p. — ISBN 9781449324766.
    • Перевод на русский язык:
      Мински, Мадхавапедди, Хикки. Программирование на языке OCaml. — ДМК, 2014. — 536 с. — ISBN 978-5-97060-102-0.
  • Andreas Rossberg. 1ML – Core and Modules United (F-ing First-class Modules). — , 2015.
  • Andreas Rossberg. 1ML with Special Effects (F-ing Generativity Polymorphism). — WadlerFest, Google, 2016.
  • Haskell-Wiki: Existential types.
  • Haskell-Wiki: Rank-N types.
  • Haskell-Wiki: Impredicative types.
  • Jacques Garrigue. OCaml manual: Polymorphic variants.

Википедия, чтение, книга, библиотека, поиск, нажмите, истории, книги, статьи, wikipedia, учить, информация, история, скачать, скачать бесплатно, mp3, видео, mp4, 3gp, jpg, jpeg, gif, png, картинка, музыка, песня, фильм, игра, игры, мобильный, телефон, Android, iOS, apple, мобильный телефон, Samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Сеть, компьютер, Информация о Полиморфизм типов, Что такое Полиморфизм типов? Что означает Полиморфизм типов?

Parametricheskij polimorfizm v yazykah programmirovaniya i teorii tipov svojstvo semantiki sistemy tipov pozvolyayushee obrabatyvat znacheniya raznyh tipov identichnym obrazom to est ispolnyat fizicheski odin i tot zhe kod dlya dannyh raznyh tipov Parametricheskij polimorfizm schitaetsya istinnoj formoj polimorfizma delaya yazyk bolee vyrazitelnym i sushestvenno povyshaya koefficient povtornogo ispolzovaniya koda Tradicionno emu protivopostavlyaetsya ad hoc polimorfizm predostavlyayushij edinyj interfejs k potencialno razlichnomu kodu dlya raznyh dopustimyh v dannom kontekste tipov potencialno ne sovmestimyh staticheski ili dinamicheski V ryade ischislenij naprimer v teorii kvalificirovannyh tipov ad hoc polimorfizm rassmatrivaetsya kak chastnyj sluchaj parametricheskogo Parametricheskij polimorfizm lezhit v osnove sistem tipov yazykov semejstva ML takie sistemy tipov nazyvayut polimorfnymi V soobshestvah yazykov s nepolimorfnymi sistemami tipov potomki Algola i BCPL parametricheski polimorfnye funkcii i tipy nazyvayut obobshyonnymi Polimorfizm tipovTermin parametricheskij polimorfizm tradicionno ispolzuetsya dlya oboznacheniya tipobezopasnogo parametricheskogo polimorfizma hotya sushestvuyut i netipizirovannye ego formy sm parametricheskij polimorfizm v Si i C Klyuchevym ponyatiem tipobezopasnogo parametricheskogo polimorfizma pomimo polimorfnoj funkcii yavlyaetsya polimorfnyj tip Polimorfnyj tip angl polymorphic type ili politip angl polytype eto tip parametrizovannyj drugim tipom Parametr v sloe tipov nazyvaetsya peremennoj tipa ili ti povoj peremennoj Formalno polimorfizm tipov izuchaetsya v polimorfno tipizirovannom lyambda ischislenii nazyvaemom Sistemoj F Naprimer funkciya append sceplyayushaya dva spiska v odin mozhet byt postroena nezavisimo ot tipa elementov spiska Pust ti povaya peremennaya a opisyvaet tip elementov spiska Togda funkciya append mozhet byt tipizirovana kak forall a a a gt a zdes konstrukciya a oznachaet tip spisok kazhdyj element kotorogo imeet tip a sintaksis prinyatyj v yazyke Haskell V etom sluchae govoryat chto tip parametrizovan peremennoj a dlya vseh znachenij a V kazhdom meste primeneniya append k konkretnym argumentam znachenie a razreshaetsya prichyom kazhdoe eyo upominanie v angl podmenyaetsya znacheniem sootvetstvuyushim kontekstu primeneniya Takim obrazom v dannom sluchae signatura funkcionalnogo tipa trebuet identichnosti tipov elementov oboih spiskov i rezultata Mnozhestvo dopustimyh znachenij peremennoj tipa zadayotsya posredstvom kvantifikacii Prostejshimi kvantorami yavlyayutsya universalnyj kak v primere s append i ekzistencialnyj sm dalee Kvalificirovannyj tip angl qualified type eto polimorfnyj tip dopolnitelno snabzhyonnyj naborom predikatov reglamentiruyushih spektr dopustimyh znachenij parametra etogo tipa Inache govorya kvalifikaciya tipa pozvolyaet upravlyat kvantifikaciej proizvolnym obrazom Teoriyu kvalificirovannyh tipov postroil Mark Dzhons Mark P Jones v 1992 godu Ona predostavlyaet obshee obosnovanie dlya samyh ekzotichnyh sistem tipov vklyuchaya klassy tipov rasshiryaemye zapisi i angl i pozvolyaet tochno formulirovat osobye ogranicheniya dlya konkretnyh polimorfnyh tipov ustanavlivaya takim obrazom otnosheniya mezhdu parametricheskim i ad hoc polimorfizmom peregruzkoj a takzhe mezhdu yavnoj i neyavnoj peregruzkoj Svyaz tipa s predikatom v etoj teorii nazyvaetsya svidetelstvom angl evidence Dlya svidetelstv sformulirovana algebra analogichnaya lyambda ischisleniyu vklyuchayushaya abstrakciyu svidetelstv primenenie svidetelstv i t d Sootnesenie terma etoj algebry s yavno peregruzhennoj funkciej nazyvaetsya translyaciej svidetelstva angl evidence translation Motiviruyushimi primerami dlya razrabotki obobshyonnoj teorii posluzhili klassy tipov Vadlera Blotta i tipizaciya rasshiryaemyh zapisej posredstvom predikatov Harpera Pirsa Klassifikaciya polimorfnyh sistemImeetsya vikiuchebnik po teme en Haskell Polymorphism Parametricheski polimorfnye sistemy tipov principialno klassificiruyutsya po rangu i po svojstvu predikativnosti Krome togo razlichayutsya yavnyj i neyavnyj polimorfizm i ryad drugih svojstv Neyavnyj polimorfizm obespechivaetsya za schyot vyvedeniya tipov chto sushestvenno povyshaet udobstvo ispolzovaniya no imeet ogranichennuyu vyrazitelnost Mnogie prakticheskie parametricheski polimorfnye yazyki razdelyayut fazy vneshnego neyavno tipizirovannogo yazyka angl external implicitly typed language i vnutrennego yavno tipizirovannogo angl internal explicitly typed language Naibolee obshej formoj polimorfizma yavlyaetsya impredikativnyj polimorfizm vysshih rangov Naibolee populyarnymi ogranicheniyami etoj formy yavlyayutsya polimorfizm 1 go ranga nazyvaemyj preneksnym i predikativnyj polimorfizm Vmeste oni obrazuyut predikativnyj preneksnyj polimorfizm blizkij k realizovannomu v ML i v rannih versiyah Haskela S uslozhneniem sistem tipov signatury tipov stanovyatsya nastolko slozhnymi chto polnoe ili pochti polnoe ih vyvedenie nachinaet rassmatrivatsya mnogimi issledovatelyami kak kritichnoe svojstvo otsutstvie kotorogo sdelaet yazyk neprigodnym dlya praktiki Naprimer dlya tradicionnogo kombinatora a href wiki Map D0 BF D1 80 D0 BE D0 B3 D1 80 D0 B0 D0 BC D0 BC D0 B8 D1 80 D0 BE D0 B2 D0 B0 D0 BD D0 B8 D0 B5 title Map programmirovanie map a polnaya signatura tipa s uchyotom rodovoj kvantifikacii v usloviyah tipobezopasnogo otslezhivaniya potoka isklyuchenij prinimaet sleduyushij vid kak i vyshe a oznachaet spisok elementov tipa a valmap a b g d a gb d a g b displaystyle val map colon forall alpha colon star cdot forall beta colon star cdot forall gamma colon emptyset cdot forall delta colon emptyset cdot alpha xrightarrow gamma beta xrightarrow delta left alpha right xrightarrow gamma left beta right Rang Rang polimorfizma pokazyvaet dopustimuyu v ramkah sistemy glubinu vlozheniya kvantorov peremennyh tipa Polimorfizm ranga k pri k gt 1 pozvolyaet konkretizirovat peremennye tipa polimorfnymi tipami ranga ne vyshe k 1 Polimorfizm vysshih rangov pozvolyaet stavit kvantory peremennyh tipa sleva ot proizvolnogo chisla strelok v tipah vysshih poryadkov Dzho Uells angl Joe Wells dokazal chto vyvedenie tipov dlya Sistemy F tipizirovannoj po Karri nerazreshimo dlya rangov vyshe 2 go tak chto pri ispolzovanii bolee vysokih rangov neobhodimo ispolzovat yavnoe annotirovanie tipami Sushestvuyut sistemy tipov s chastichnym vyvedeniem trebuyushie annotirovaniya tolko nevyvodimyh ti povyh peremennyh Preneksnyj polimorfizm Polimorfizm ranga 1 chasto nazyvaetsya preneksnym ot slova preneks sm angl V preneksno polimorfnoj sisteme peremennye tipa ne mogut konkretizirovatsya polimorfnymi tipami Eto ogranichenie delaet razlichie mezhdu monomorfnymi i polimorfnymi tipami sushestvennym iz za chego v preneksnoj sisteme polimorfnye tipy neredko nazyvayut shemami tipizacii angl type schemas dlya otlicheniya ih ot obychnyh monomorfnyh tipov monotipov Kak sledstvie vse tipy mogut byt zapisany v forme kogda vse kvantory peremennyh tipa vyneseny v samuyu vneshnyuyu preneksnuyu poziciyu chto i nazyvaetsya angl Proshe govorya razreshaetsya polimorfnoe opredelenie funkcij no zapreshaetsya peredavat polimorfnye funkcii v kachestve argumentov drugim funkciyam polimorfno opredelyonnye funkcii dolzhny byt instancirovany monotipom pered ispolzovaniem Blizkim ekvivalentom yavlyaetsya tak nazyvaemyj Let polimorfizm ili polimorfizm v stile ML Damasa Milnera Tehnicheski Let polimorfizm v ML imeet dopolnitelnye sintaksicheskie ogranicheniya takie kak ogranichenie na znacheniya value restriction svyazannoe s problemoj tipobezopasnosti pri ispolzovanii ssylok ne voznikayushih v chistyh yazykah takih kak Haskell i Clean Predikativnost Predikativnyj polimorfizm Predikativnyj ogranichennyj usloviem polimorfizm trebuet chtoby peremennaya tipa byla konkretizirovana monotipom ne politipom K predikativnym sistemam otnosyatsya intuicionistskaya teoriya tipov i angl Impredikativnyj polimorfizm Impredikativnyj bezuslovnyj polimorfizm razreshaet konkretizirovat peremennuyu tipa proizvolnym tipom kak monomorfnym tak i polimorfnym vklyuchaya sam opredelyaemyj tip Razreshenie v ramkah nekoego ischisleniya rekursivnogo vklyucheniya sistemy v samu sebya nazyvaetsya impredikativnostyu Potencialno eto mozhet privodit k paradoksam tipa Rasselovskogo ili Kantorovskogo no v sluchae s tshatelno produmannoj sistemoj tipov etogo ne proishodit Impredikativnyj polimorfizm pozvolyaet peredavat polimorfnye funkcii drugim funkciyam v kachestve parametrov vozvrashat ih v kachestve rezultata hranit ih v strukturah dannyh i t d poetomu ego takzhe nazyvayut polimorfizmom pervogo klassa Eto naibolee moshnaya forma polimorfizma no s drugoj storony predstavlyayushaya seryoznuyu problemu dlya optimizacii i delayushaya vyvedenie tipov nerazreshimym Primerom impredikativnoj sistemy yavlyaetsya Sistema F i eyo rasshireniya sm lyambda kub Podderzhka rekursii Osnovnaya statya Polimorfnaya rekursiya angl Tradicionno v potomkah ML funkciya mozhet byt polimorfnoj tolko pri vzglyade izvne to est eyo mozhno primenyat k argumentam razlichnyh tipov no eyo opredelenie mozhet soderzhat tolko monomorfnuyu rekursiyu to est razreshenie tipov osushestvlyaetsya do vyzova Rasprostranenie rekonstrukcii tipov po ML na rekursivnye tipy ne predstavlyaet sereznyh trudnostej S drugoj storony sochetanie rekonstrukcii tipov s rekursivno opredelyonnymi termami porozhdaet slozhnuyu problemu izvestnuyu pod nazvaniem angl Majkroft Mycroft i Mejrtens Meertens predlozhili polimorfnoe pravilo tipizacii pozvolyayushee konkretizirovat razlichnymi tipami rekursivnye vyzovy rekursivnoj funkcii iz eyo sobstvennogo tela V etom ischislenii izvestnom kak ischislenie Milnera Majkrofta vyvedenie tipov nerazreshimo Polimorfizm strukturnyh tipovTipy proizvedeniya takzhe izvestnye kak zapisi sluzhat formalnoj bazoj dlya obektno orientirovannogo i modulnogo programmirovaniya Ih dvojstvennuyu paru sostavlyayut tipy summy takzhe izvestnye kak angl a b a b displaystyle neg lbrace a land b rbrace langle neg a lor neg b rangle a b a b displaystyle neg langle a lor b rangle lbrace neg a land neg b rbrace Vmeste oni yavlyayutsya sredstvom vyrazheniya lyubyh slozhnyh struktur dannyh i nekotoryh aspektov povedeniya programm Ischislenie zapisej angl record calculi obobshyonnoe nazvanie problemy i ryada eyo reshenij kasayushihsya voprosov gibkosti tipov proizvedenij v yazykah programmirovaniya pri uslovii tipobezopasnosti Termin neredko rasprostranyaetsya i na tipy summy a granicy ponyatiya tip zapisi mogut varirovatsya ot ischisleniya k ischisleniyu kak i samo ponyatie tip Primenyayutsya takzhe terminy polimorfizm zapisej chto opyat zhe zachastuyu vklyuchaet v sebya polimorfizm variantov ischislenie modulej i strukturnyj polimorfizm Obshie svedeniya Proizvedeniya i summy tipov zapisi i angl obespechivayut gibkost pri postroenii slozhnyh struktur dannyh no ogranicheniya mnogih realnyh sistem tipov zachastuyu ne pozvolyayut ispolzovat ih po nastoyashemu gibko Eti ogranicheniya obychno voznikayut v svyazi s voprosami effektivnosti vyvedeniya tipov ili prosto udobstva ispolzovaniya Klassicheskim primerom mozhet sluzhit yazyk Standard ML sistema tipov kotorogo byla umyshlenno ogranichena rovno nastolko chtoby sochetat prostotu realizuemosti s vyrazitelnostyu i matematicheski dokazuemoj tipobezopasnostyu Primer opredeleniya zapisi gt val r name Foo used true val r name string used bool name Foo used true Dostup k znacheniyu polya po ego imeni osushestvlyaetsya prefiksnoj konstrukciej vida field record gt val r1 name r val r1 string Foo Sleduyushee opredelenie funkcii nad zapisyu yavlyaetsya korrektnym gt fun name1 x name string age int name x A sleduyushee porozhdaet oshibku kompilyatora o tom chto tip ne razreshyon polnostyu gt fun name2 x name x unresolved type in declaration name 1 Monomorfizm zapisej delaet ih negibkim no effektivnym sredstvom poskolku fakticheskoe raspolozhenie v pamyati kazhdogo polya zapisi izvestno zaranee na etape kompilyacii obrashenie k nemu po imeni kompiliruetsya v pryamuyu indeksaciyu chto obychno vychislyaetsya za odnu mashinnuyu instrukciyu Odnako pri razrabotke slozhnyh masshtabiruemyh sistem zhelatelno imet vozmozhnost abstragirovat polya ot konkretnyh zapisej naprimer opredelit universalnyj selektor polej fun select r l l r No kompilyaciya polimorfnogo obrasheniya k polyam kotorye mogut raspolagatsya v raznom poryadke v raznyh zapisyah predstavlyaet slozhnuyu problemu kak s tochki zreniya kontrolya bezopasnosti operacij na urovne yazyka tak i s tochki zreniya bystrodejstviya na urovne mashinnogo koda Naivnym resheniem mozhet byt dinamicheskij poisk po slovaryu pri kazhdom obrashenii i skriptovye yazyki ego primenyayut odnako ochevidno chto eto chrezvychajno neeffektivno Summy tipov sostavlyayut osnovu vyrazheniya vetvleniya prichyom za schyot strogosti sistemy tipov kompilyator obespechivaet kontrol za polnotoj razbora Naprimer dlya sleduyushego tipa summy datatype a foo A of a B of a a C vsyakaya funkciya nad nim budet imet vid fun bar p a foo case p of A x gt B x y gt C gt i pri udalenii lyubogo iz predlozhenij kompilyator vydast preduprezhdenie o nepolnote razbora match nonexhaustive Dlya sluchaev kogda iz mnozhestva variantov lish nekotorye trebuyut analiza v dannom kontekste mozhno organizovat default vetvlenie pri pomoshi t n dzhokera universalnogo obrazca s kotorym sopostavimy vse dopustimye soglasno tipizacii znacheniya Dlya ego zapisi ispolzuetsya simvol podchyorkivaniya Naprimer fun bar p a foo case p of C gt gt V nekotoryh yazykah v Standard ML v Haskell dazhe bolee prostaya konstrukciya if then else yavlyaetsya lish sintaksicheskim saharom nad chastnym sluchaem vetvleniya to est vyrazhenie if A then B else C uzhe na etape grammaticheskogo razbora predstavlyaetsya v vide case A of true gt B false gt C libo case A of true gt B gt C Sintaksicheskij sahar V Standard ML zapisi i varianty yavlyayutsya monomorfnymi odnako podderzhivaetsya sintaksicheskij sahar dlya raboty s zapisyami so mnozhestvom polej nazyvaemyj universalnym obrazcom gt val r name Foo used true val r name string used bool name Foo used true gt val used u r val u bool true Mnogotochie v tipe used oznachaet chto v dannoj zapisi sushestvuyut i drugie polya pomimo upomyanutyh Odnako polimorfizm zapisej kak takovoj otsutstvuet dazhe preneksnyj trebuetsya polnoe staticheskoe razreshenie informacii o monomorfnom tipe zapisi posredstvom vyvedeniya ili yavnogo annotirovaniya Rasshirenie i funkcionalnoe obnovlenie zapisej Termin rasshiryaemye zapisi extensible records ispolzuetsya dlya obobshyonnogo oboznacheniya takih operacij kak rasshirenie postroenie novoj zapisi na osnove imeyushejsya s dobavleniem novyh polej obrezanie vzyatie ukazannoj chasti ot imeyushejsya zapisi i dr V chastnosti on podrazumevaet vozmozhnost tak nazyvaemogo funkcionalnogo obnovleniya zapisej functional record update operacii postroeniya novogo znacheniya zapisi na osnove imeyushegosya putyom kopirovaniya imyon i tipov ego polej pri kotoroj odno ili neskolko polej v novoj zapisi poluchayut novye znacheniya otlichayushiesya ot ishodnyh i vozmozhno imeyushie drugoj tip Sami po sebe operacii funkcionalnogo obnovleniya i rasshireniya ortogonalny polimorfizmu zapisej no ih polimorfnoe ispolzovanie predstavlyaet osobyj interes Dazhe dlya monomorfnyh zapisej priobretaet bolshoe znachenie vozmozhnost opuskat yavnoe upominanie polej kopiruemyh bez izmenenij a eto fakticheski predstavlyaet soboj polimorfizm zapisej v chisto sintaksicheskoj forme S drugoj storony esli rassmatrivat vse zapisi v sisteme kak rasshiryaemye to eto pozvolyaet tipizirovat funkcii nad zapisyami kak polimorfnye Primer prostejshego varianta konstrukcii realizovan v Alice ML soglasno dejstvuyushim soglasheniyam po Universalnyj obrazec mnogotochie imeet rasshirennye vozmozhnosti posredstvom ego mozhno osushestvlyat zahvat ryada s tem chtoby rabotat s ostavshejsya chastyu zapisi kak so znacheniem gt val r a 1 b true c hello r a 1 b true c hello gt val a n r1 r r1 b true c hello gt val r2 d 3 14 r1 r2 b true c hello d 3 14 Funkcionalnoe obnovlenie realizuetsya kak proizvodnaya forma ot zahvata ryada s pomoshyu sluzhebnogo slova where Naprimer sleduyushij kod gt let val r a 1 c 3 0 d not a list f 1 p not a string z NONE in r where d nil p hello end budet avtomaticheski perepisan v forme gt let val r a 1 c 3 0 d not a list f 1 p not a string z NONE val d p tmp r in tmp d nil p hello end Konkatenaciya zapisej Odnimi iz pervyh konec 1980 h nachalo 1990 h byli predlozheny razlichnye varianty formalizacii rasshiryaemyh zapisej cherez operacii konkatenacii nad nepolimorfnymi zapisyami Harper Pirs Vand Salcmann angl dazhe ispolzoval operacii nad zapisyami vmesto polimorfizma v yazyke Amber Dlya etih ischislenij net izvestnogo sposoba effektivnoj kompilyacii krome togo eti ischisleniya vesma slozhny i s tochki zreniya teoretiko ti povogo analiza Naprimer val car name Toyota age old id 6678 val truck name Toyota id 19823235 val repaired truck car and truck Vand avtor ryadnogo polimorfizma pokazal chto posredstvom konkatenacii zapisej mozhno modelirovat mnozhestvennoe nasledovanie Strukturnaya podtipizaciya Kardelli angl Luca Cardelli issledoval vozmozhnost formalizovat polimorfizm zapisej posredstvom otnoshenij podtipizacii na zapisyah dlya etogo zapis rassmatrivaetsya kak universalnyj podtip to est razreshaetsya otnesenie eyo znacheniya ko vsemu mnozhestvu eyo supertipov Etot podhod takzhe podderzhivaet nasledovanie metodov i sluzhit teoretiko ti povoj bazoj dlya naibolee rasprostranyonnyh form obektno orientirovannogo programmirovaniya Kardelli predstavil variant metoda kompilyacii polimorfizma zapisej cherez ih podtipy posredstvom predopredeleniya smesheniya vseh vozmozhnyh metok v potencialno ogromnoj strukture so mnozhestvom pustyh slotov Metod imeet sushestvennye nedostatki Podderzhka podtipizacii v sisteme tipov sushestvenno uslozhnyaet mehanizm proverki soglasovaniya tipov Krome togo v eyo prisutstvii staticheskij tip vyrazheniya perestayot predostavlyat polnuyu informaciyu o dinamicheskoj strukture znacheniya zapisi Naprimer pri ispolzovanii tolko podtipov sleduyushij term gt if true then A 1 B true else B false C Cat val it B bool imeet tip B bool no ego dinamicheskoe znachenie ravno A 1 B true to est informaciya o tipe rasshiryaemoj zapisi teryaetsya chto predstavlyaet seryoznuyu problemu dlya proverki operacij trebuyushih dlya svoego ispolneniya polnoj informacii o strukture znacheniya takih kak sravnenie na ravenstvo Nakonec pri nalichii podtipov vybor mezhdu uporyadochennym i neuporyadochennym predstavleniem zapisej seryozno vliyaet na proizvoditelnost Populyarnost podtipizacii obuslovlena tem chto ona predostavlyaet prostye i naglyadnye resheniya dlya mnogih zadach Naprimer obekty raznyh tipov mozhno pomeshat v edinyj spisok esli oni imeyut obshij supertip Ryadnyj polimorfizm Vanda angl Mitchell Wand v 1987 godu predlozhil ideyu zahvatyvat informaciyu ob ostavshejsya ne ukazannoj yavno chasti zapisi posredstvom togo chto on nazval ryadnoj ti povoj peremennoj row type variable Ryadnaya peremennaya eto peremennaya tipa probegayushaya mnozhestvo konechnyh naborov ryadov tipizirovannyh polej par znachenie tip V rezultate poyavlyaetsya vozmozhnost realizovat nasledovanie vshirinu neposredstvenno na osnove parametricheskogo polimorfizma lezhashego v osnove ML bez uslozhneniya sistemy tipov pravilami angl Poluchaemuyu raznovidnost polimorfizma nazyvayut ryadnym polimorfizmom row polymorphism Ryadnyj polimorfizm rasprostranyaetsya kak na proizvedeniya tipov tak i na summy tipov Vand zaimstvoval termin angl row ryad cepochka stroka iz Algola 68 gde on oznachal nabor predstavlenij V russkoyazychnoj literature etot termin v kontekste Algola tradicionno perevodilsya kak multivid Vstrechaetsya takzhe variant perevoda row variables kak strochnye peremennye kotoryj mozhet vyzvat putanicu so strochnymi bukvami v strokovyh tipah Primer yazyk OCaml sintaksis postfiksnyj record field let send m a a m value send m lt m a gt gt a lt fun gt Zdes mnogotochie iz dvuh tochek eto prinyatyj v OCaml sintaksis dlya bezymyannoj ryadnoj ti povoj peremennoj Za schyot takoj tipizacii funkciya send m mozhet byt primenena k obektu lyubogo zaranee ne izvestnogo obektnogo tipa v sostav kotorogo vhodit metod m sootvetstvuyushej signatury Vyvedenie tipov dlya ischisleniya Vanda v pervonachalnoj versii bylo nepolnym iz za otsutstviya ogranichenij na rasshirenie ryada dobavlenie polya pri sovpadenii imeni podmenit sushestvuyushee v rezultate ne vse programmy imeyut glavnyj tip Odnako eta sistema byla pervym konkretnym predlozheniem po rasshireniyu ML zapisyami podderzhivayushimi nasledovanie V posleduyushie gody byl predlozhen celyj ryad razlichnyh dorabotok v tom chisle delayushih ego polnym Naibolee zametnyj sled ostavil Dide Remi fr Didier Remy On postroil praktichnuyu sistemu tipov s rasshiryaemymi zapisyami vklyuchayushuyu polnyj i effektivnyj algoritm rekonstrukcii tipov Remi rasslaivaet yazyk tipov na formuliruya sortirovannuyu algebru tipov angl sorted algebra of types sorted language of types Razlichayutsya sort sobstvenno tipov v tom chisle tipov polej i sort polej vvodyatsya otobrazheniya mezhdu nimi i na ih osnove formuliruyutsya pravila tipizacii rasshiryaemyh zapisej kak prostoe rasshirenie klassicheskih pravil ML Informaciya o prisutstvii angl presence polya opredelyaetsya kak otobrazhenie iz sorta tipov v sort polej Ryadnye ti povye peremennye pereformuliruyutsya kak peremennye prinadlezhashie sortu polej i ravnye konstante otsutstviya angl absence yavlyayushejsya elementom sorta polej ne imeyushim sootvetstviya v sorte tipov Operaciya vychisleniya tipa dlya zapisi iz n polej opredelyaetsya kak otobrazhenie n arnogo polya v tip gde kazhdoe pole v kortezhe libo vychislyaetsya funkciej prisutstviya libo zadayotsya konstantoj otsutstviya Uproshyonno ideyu ischisleniya mozhno traktovat kak rasshirenie tipa vsyakogo polya zapisi flagom prisutstviya otsutstviya i predstavlenie zapisi v vide kortezha so slotom dlya kazhdogo vozmozhnogo polya V prototipe realizacii sintaksis yazyka tipov byl sdelan priblizhennym k teoretiko ti povoj formulirovke naprimer let car name Toyota age old id 7866 car name pre string id pre num age pre string abs let truck name Blazer id 6587867567 truck name pre string id pre num abs let person name Tim age 31 id 5656787 person name pre string id pre num age pre num abs simvol u Remi oznachaet operaciyu vychisleniya tipa Dobavlenie novogo polya zapisyvaetsya s pomoshyu konstrukcii with let driver person with vehicle car driver vehicle pre name pre string id pre num age pre string abs name pre string id pre num age pre num abs Funkcionalnoe obnovlenie zapisyvaetsya identichno s toj raznicej chto upominanie uzhe sushestvuyushego polya pereopredelyaet ego let truck driver driver with vehicle truck truck driver vehicle pre name pre string id pre num abs name pre string id pre num age pre num abs Eta shema formalizuet ogranichenie neobhodimoe dlya proverki operacij nad zapisyami i vyvedeniya glavnogo tipa no ne vedyot k ochevidnoj i effektivnoj realizacii Remi ispolzuet heshirovanie chto dovolno effektivno v srednem no uvelichivaet izderzhki vo vremya ispolneniya dazhe dlya ishodno monomorfnyh programm i ploho podhodit dlya zapisej s bolshim chislom polej V dalnejshem Remi issledoval ispolzovanie ryadnogo polimorfizma sovmestno s angl podcherknuv chto eto ortogonalnye ponyatiya i pokazav chto zapisi stanovyatsya naibolee vyrazitelnymi pri ih odnovremennom ispolzovanii Na etoj osnove on sovmestno s Zheromom Vujonom fr Jerome Vouillon predlozhil legkovesnoe obektno orientirovannoe rasshirenie dlya ML Eto rasshirenie bylo realizovano v yazyke Caml Special Light Ksave Lerua prevrativ ego v OCaml Obektnaya model OCaml tesno spletaet ispolzovanie strukturnoj podtipizacii i ryadnogo polimorfizma iz za chego poroj ih oshibochno otozhdestvlyayut Ryadnyj polimorfizm proizvedenij v OCaml lezhit v osnove vyvedeniya tipov otnosheniya podtipizacii ne yavlyayutsya neobhodimymi v yazyke s ego podderzhkoj no dopolnitelno povyshayut gibkost na praktike V OCaml realizovan bolee prostoj i naglyadnyj sintaksis dlya informacii o tipah Zhak Garri ga fr Jacques Garrigue realizoval praktichnuyu sistemu polimorfnyh summ On sovmestil teoreticheskie raboty Remi i Ohori postroiv sistemu prolegayushuyu poseredine informaciya o nalichii metok v zapisi predstavlyaetsya posredstvom ispolzovaniya rodo v a informaciya ob ih tipah ispolzuet ryadnye peremennye Chtoby kompilyator mog otlichat polimorfnye summy ot monomorfnyh Garriga ispolzuet specialnyj sintaksis obratnyj apostrof predvaryayushij teg Pri etom ischezaet neobhodimost v obyavlenii tipa mozhno srazu pisat funkcii nad nim i kompilyator budet vyvodit minimalnyj spisok tegov po mere kompozicii etih funkcij Eta sistema stala chastyu OCaml okolo 2000 goda no ne vmesto a v dopolnenie k monomorfnym summam tak kak oni neskolko menee effektivny i iz za nevozmozhnosti kontrolya polnoty razbora zatrudnyayut poisk oshibok v otlichie ot resheniya Blyuma Nedostatki ryadnogo polimorfizma Vanda neochevidnost realizacii net edinogo sistematichnogo sposoba ego kompilirovat kazhdaya konkretnaya sistema tipov na osnove ryadnyh peremennyh imeet svoyu realizaciyu i neodnoznachnoe sootnoshenie s teoriej net edinoobraznoj formulirovki dlya proverki i vyvedeniya tipov podderzhka vyvedeniya reshalas otdelno i potrebovala eksperimentov s nalozheniem razlichnyh ogranichenij Prosvechivayushie summy Harpera Lilibridzha Naibolee slozhnoj raznovidnostyu zapisej yavlyayutsya zavisimye zapisi Takie zapisi mogut vklyuchat v sebya tipy naravne s obychnymi znacheniyami materializovannye tipy reificirovannye prichyom termy i tipy sleduyushie dalee po poryadku v tele zapisi mogut byt opredeleny na osnove predshestvuyushih im Takie zapisi sootvetstvuyut slabym summam iz teorii zavisimyh tipov takzhe izvestnym kak ekzistencialy i sluzhat naibolee obshim obosnovaniem sistem modulej yazykov programmirovaniya angl rassmatrival analogichnye po svojstvam tipy kak odin iz osnovnyh tipov v polnotipovom programmirovanii no nazyval ih kortezhami angl Robert Harper i Mark Lilibridzh Mark Lillibridge postroili ischislenie prosvechivayushih summ angl translucent sums dlya formalnogo obosnovaniya yazyka modulej pervogo klassa vysshego poryadka naibolee razvitoj sistemy modulej sredi izvestnyh Eto ischislenie v tom chisle primenyaetsya v semantike Harpera Stouna predstavlyayushej teoretiko ti povoe obosnovanie dlya Standard ML Prosvechivayushie summy obobshayut slabye summy za schyot metok i nabora ravenstv opisyvayushih konstruktory tipov Termin prosvechivayushie angl translucent oznachaet chto v sostave tipa zapisi mogut prisutstvovat kak tipy s yavno eksportirovannoj strukturoj tak i polnostyu abstraktnye Sloj rodo v v ischislenii imeet prostoj klassicheskij sostav razlichayutsya rod vseh tipov displaystyle star i funkcionalnye roda vida k1 gt k2 displaystyle k 1 gt k 2 tipiziruyushie konstruktory tipov ML ne podderzhivaet polimorfizma v vysshih roda h vse peremennye tipa prinadlezhat k rodu displaystyle star i abstrakciya konstruktorov tipov vozmozhna lish posredstvom funktorov Ischislenie razlichaet pravila podtipizacii dlya zapisej kak osnovnyh tipov i dlya polej zapisej kak ih sostavlyayushih sootvetstvenno rassmatrivaya podtipy i podpolya a zatemnenie abstragirovanie signatur polej yavlyaetsya otdelnym ot podtipizacii ponyatiem Podtipizaciya zdes formalizuet sopostavlenie modulej s interfejsami Ischislenie Harpera Lilibridzha nerazreshimo dazhe v chasti proverki soglasovaniya tipov dialekty yazyka modulej realizovannye v Standard ML i OCaml ispolzuyut ogranichennye podmnozhestva etogo ischisleniya Odnako pozzhe Andreas Rossberg angl Andreas Rossberg na osnove ih idej postroil yazyk 1ML v kotorom tradicionnye zapisi urovnya yadra yazyka i struktury urovnya modulej yavlyayutsya odnoj i toj zhe pervoklassnoj konstrukciej sushestvenno bolee vyrazitelnoj chem u Kardelli sm kritika yazyka modulej ML Za schyot podklyucheniya idei Harpera i Mitchela o podrazdelenii vseh tipov na angl malenkih i bolshih tipov uproshyonno eto pohozhe na fundamentalnoe razdelenie tipov na prostye i agregatnye s neodinakovymi pravilami tipizacii Rossberg obespechil razreshimost ne tolko proverki soglasovaniya no i pochti polnogo vyvedeniya tipov Bolee togo 1ML dopuskaet impredikativnyj polimorfizm Pri etom vnutrennij yazyk v 1ML osnovan na ploskoj angl i ne trebuet ispolzovaniya zavisimyh tipov v kachestve metateorii Na 2015 god Rossberg ostavil otkrytym vopros o vozmozhnosti dobavleniya v 1ML ryadnogo polimorfizma otmetiv lish chto eto dolzhno obespechit bolee polnoe vyvedenie tipov Spustya god on dobavil v 1ML polimorfizm effektov Polimorfnoe ischislenie zapisej Ohori Acusi Ohori angl Atsushi Ohori sovmestno so svoim nauchnym rukovoditelem angl Peter Buneman v 1988 godu predlozhil ideyu ogranichivat spektr vozmozhnyh znachenij obychnyh tipovyh peremennyh v polimorfnoj tipizacii samih zapisej V dalnejshem Ohori formalizoval etu ideyu posredstvom rodo v zapisej postroiv k 1995 godu polnocennoe ischislenie i sposob ego effektivnoj kompilyacii Prototip realizacii byl sozdan v 1992 godu kak rasshirenie kompilyatora angl zatem Ohori vozglavil razrabotku sobstvennogo kompilyatora SML realizuyushego odnoimyonnyj dialekt yazyka Standard ML V SML polimorfizm zapisej sluzhit osnovoj dlya besshovnogo vstraivaniya konstrukcij na SQL v programmy na SML SML primenyaetsya krupnymi yaponskimi kompaniyami dlya resheniya biznes zadach svyazannyh s nagruzhennymi bazami dannyh Primer takogo roda sessii REPL fun wealthy Salary s s gt 100000 val wealthy fn a Salary int gt bool fun young x Age x lt 24 val young fn a Age int gt bool fun youngAndWealthy x wealthy x andalso young x val youngAndWealthy fn a Age int Salary int gt bool fun select display l pred fold fn x y gt if pred x then display x y else y l nil val select fn a gt b gt a list gt a gt bool gt b list fun youngAndWealthyEmployees l select Name l youngAndWealthy val youngAndWealthyEmployees fn b Age int Name a Salary int list gt a list Ohori nazval svoyo ischislenie polimorfizmom zapisej angl record polymorphism ili polimorfnym ischisleniem zapisej angl polymorphic record calculus odnovremenno podcherknuv chto on kak i Vand rassmatrivaet polimorfizm ne tolko tipov proizvedenij no i tipov summ Ischislenie Ohori vydelyaetsya naibolee intensivnym ispolzovaniem sloya rodo v V zapisi t k displaystyle t colon colon k otnesenie tipa t displaystyle t k rodu k displaystyle k simvol k displaystyle k oznachaet libo rod vseh tipov U displaystyle U libo rod zapisej imeyushih formu l1 t1 ln tn displaystyle left left l 1 colon t 1 dots l n colon t n right right oboznachayushij mnozhestvo vseh zapisej soderzhashih kak minimum ukazannye polya libo rod variantov imeyushih formu l1 t1 ln tn displaystyle left langle left langle l 1 t 1 dots l n colon t n right rangle right rangle oboznachayushij mnozhestvo vseh variantnyh tipov soderzhashih kak minimum ukazannye konstruktory V ploskom sintaksise yazyka ogranichenie tipa nekotorym rodom zapisi zapisyvaetsya kak t sm primery vyshe Reshenie v nekotoroj stepeni shozhe s angl Kardelli Vegnera Edinstvennaya polimorfnaya operaciya predusmotrennaya etim ischisleniem operaciya izvlecheniya polya Odnako Ohori byl pervym kto predstavil dlya polimorfizma zapisej prostuyu i effektivnuyu shemu kompilyacii On nazval eyo ischisleniem realizacij implementation calculus Zapis predstavlyaetsya vektorom uporyadochennym leksikograficheski po imenam polej ishodnoj zapisi obrashenie k polyu po imeni transliruetsya v vyzov promezhutochnoj funkcii vozvrashayushej nomer dannogo polya v dannom vektore po zaprashivaemomu imeni i posleduyushuyu indeksaciyu vektora po vychislennomu nomeru pozicii Funkciya vyzyvaetsya tolko pri instancirovanii polimorfnyh termov chto nakladyvaet minimalnyj overhed na rantajm pri ispolzovanii polimorfizma i ne nakladyvaet nikakogo overheda pri rabote s monomorfnymi tipami Metod rabotaet odinakovo horosho s proizvolno bolshimi zapisyami i variantami Ischislenie obespechivaet vyvedenie tipov i nahodit strogoe sootvetstvie s teoriej rodovaya kvantifikaciya napryamuyu sootnositsya s obychnoj indeksaciej vektora predstavlyaya soboj neposredstvenno rasshirenie lyambda ischislenie vtorogo poryadka Zhirara Rejnoldsa chto pozvolyaet perenosit razlichnye izvestnye svojstva polimorfnoj tipizacii na polimorfizm zapisej Na praktike podderzhka polimorfnyh variantov v SML ne byla realizovana iz za eyo nesovmestimosti s mehanizmom opredeleniya tipov summ v Standard ML trebuetsya sintaksicheskoe razdelenie summ i rekursivnyh tipov Nedostatkom ischisleniya Ohori yavlyaetsya otsutstvie podderzhki operacij rasshireniya ili obrezaniya zapisej Pervoklassnye metki Gastera Dzhonsa V teorii kvalificirovannyh tipov rasshiryaemye zapisi opisyvayutsya predikatami otsutstviya polya lacks predicate i prisutstviya polya has predicate Benedikt Gaster Benedict R Gaster sovmestno s avtorom teorii Markom Dzhonsom Mark P Jones dorabotal eyo v chasti rasshiryaemyh zapisej do praktichnoj sistemy tipov neyavno tipizirovannyh yazykov v tom chisle opredeliv sposob kompilyacii Oni vvodyat termin pervoklassnye metki first class labels podchyorkivayushij vozmozhnost abstragirovat operacii nad polyami ot staticheski izvestnyh metok V dalnejshem Gaster zashitil na postroennoj sisteme dissertaciyu Ischislenie Gastera Dzhonsa ne obespechivaet polnoe vyvedenie tipov Krome togo iz za problem razreshimosti bylo nalozheno iskusstvennoe ogranichenie zapret na pustye ryady Sulcmann predprinyal popytku reformulirovaniya ischisleniya odnako postroennaya im sistema ne mozhet byt rasshirena do podderzhki polimorfnogo rasshireniya zapisej i ne imeet universalnogo metoda effektivnoj kompilyacii Da an Le jen Daan Leijen dobavil v ischislenie Gastera Dzhonsa predikat ryadnogo ravenstva ili ravenstva ryada angl row equality predicate i peremestil yazyk ryadov v yazyk predikatov eto obespechilo polnoe vyvedenie tipov i snyalo zapret na pustye ryady Pri kompilyacii zapisi preobrazuyutsya v leksikograficheski uporyadochennyj kortezh i primenyaetsya translyaciya svidetelstv po sheme Gastera Dzhonsa Sistema Lejena pozvolyaet vyrazhat takie idiomy kak angl naibolee moshnuyu formu obektno orientirovannogo programmirovaniya i pervoklassnye vetvleniya Na osnove etih rabot realizovany rasshireniya yazyka Haskell Rezultaty Gastera Dzhonsa ochen blizki k rezultatam Ohori nesmotrya na sushestvennye razlichiya v teoretiko ti povom obosnovanii i osnovnym preimushestvom yavlyaetsya podderzhka operacij rasshireniya i obrezaniya zapisej Nedostatkom ischisleniya yavlyaetsya to chto ono opiraetsya na svojstva sistemy tipov kotorye otsutstvuyut v bolshinstve yazykov programmirovaniya Krome togo vyvedenie tipov dlya nego predstavlyaet seryoznuyu problemu iz za chego avtory nalozhili dopolnitelnye ogranicheniya I hotya Lejen ustranil mnogie nedostatki ispolzovanie default vetvleniya nevozmozhno Polimorfizm upravlyayushih konstrukcij S razvitiem programmnyh sistem mozhet uvelichivatsya kolichestvo variantov v tipe summe i dobavlenie kazhdogo varianta trebuet dobavleniya sootvetstvuyushego vetvleniya v kazhduyu funkciyu nad etim tipom dazhe esli eti vetvleniya v raznyh funkciyah identichny Takim obrazom trudoyomkost narashivaniya funkcionalnosti v bolshinstve yazykov programmirovaniya nelinejno zavisit ot deklarativnyh izmenenij v tehnicheskom zadanii Eta zakonomernost izvestna kak angl Drugoj izvestnoj problemoj yavlyaetsya obrabotka isklyuchenij na protyazhenii desyatiletij issledovaniya sistem tipov vse yazyki otnosimye k tipobezopasnym mogli tem ne menee zavershat rabotu porozhdeniem nepojmannogo isklyucheniya poskolku nesmotrya na tipizaciyu samih isklyuchenij mehanizm ih porozhdeniya i obrabotki ne tipizirovalsya I hotya byli postroeny sredstva analiza potoka isklyuchenij eti sredstva vsegda yavlyalis vneshnimi po otnosheniyu k yazyku Matias Blyum angl Matthias Blume kollega angl rabotayushij nad proektom ego aspirant Vonsyok Chej Wonseok Chae i kollega Yumat Ejkar Umut Acar reshili obe problemy osnovyvayas na matematicheskoj dvojstvennosti proizvedenij i summ Voplosheniem ih idej stal yazyk MLPolyR osnovannyj na prostejshem podmnozhestve Standard ML i dopolnyayushij ego neskolkimi urovnyami tipobezopasnosti Pozzhe Vonsyok Chej zashitil na etih dostizheniyah dissertaciyu Reshenie sostoit v sleduyushem Soglasno principu dvojstvennosti vvodnaya forma angl introduction form dlya nekoego ponyatiya sootvetstvuet ustranyayushej forme angl elimination form dvojstvennogo emu Takim obrazom ustranyayushaya forma summ razbor vetvlenij sootvetstvuet vvodnoj forme zapisej Eto pobuzhdaet nadelit vetvleniya temi zhe svojstvami chto uzhe dostupny dlya zapisej sdelat ih pervoklassnymi obektami i dopustit ih rasshirenie Naprimer prostejshij interpretator yazyka vyrazhenij fun eval e case e of Const i gt i Plus e1 e2 gt eval e1 eval e2 s vvedeniem pervoklassnoj konstrukcii cases mozhet byt perepisan v vide fun eval e match e with cases Const i gt i Plus e1 e2 gt eval e1 eval e2 posle chego cases blok mozhet byt vynesen fun eval c eval cases Const i gt i Plus e1 e2 gt eval e1 eval e2 fun eval e match e with eval c eval Eto reshenie dopuskaet default vetvleniya v otlichie ot ischisleniya Gastera Dzhonsa chto vazhno dlya kompozicii pervoklassnyh vetvlenij Zavershenie kompozicii ryada osushestvlyaetsya s pomoshyu slova nocases fun const c d cases Const i gt i default d fun plus c eval d cases Plus e1 e2 gt eval e1 eval e2 default d fun eval e match e with const c plus c eval nocases fun bind env v1 x v2 if v1 v2 then x else env v2 fun var c env d cases Var v gt env v default d fun let c eval env d cases Let v e b gt eval bind env v eval env e b default d fun eval var env e match e with const c plus c eval var env var c env let c eval var env nocases Kak vidno novyj kod kotoryj neobhodimo dopisyvat pri kachestvennom uslozhnenii sistemy ne trebuet izmeneniya uzhe napisannogo koda funkcii const c i plus c nichego ne znayut o posleduyushem dobavlenii v interpretator yazyka podderzhki peremennyh i let blokov Takim obrazom pervoklassnye rasshiryaemye vetvleniya first class extensible cases yavlyayutsya principialnym resheniem angl pozvolyaya govorit o paradigme rasshiryaemogo programmirovaniya Po slovam Blyuma eto yavlyaetsya ne chem to principialno novym a prosto interesnym sposobom primeneniya ryadnogo polimorfizma kotoryj uzhe podderzhivaetsya v sisteme tipov i v etom smysle dostoinstvom takogo tehnicheskogo resheniya yavlyaetsya ego konceptualnaya prostota Odnako rasshirenie programmnyh sistem trebuet takzhe kontrolya nad obrabotkoj isklyuchenij kotorye mogut porozhdatsya na proizvolnoj glubine vlozheniya vyzovov I zdes Blyum s kollegami provozglashayut novyj slogan tipobezopasnosti v razvitie slogana Milnera Programmy proshedshie proverku tipov ne porozhdayut neobrabotannyh isklyuchenij Problema sostoit v tom chto esli signatura funkcionalnogo tipa vklyuchaet informaciyu o tipah isklyuchenij kotorye eta funkciya potencialno mozhet porozhdat i eta informaciya v signature peredavaemoj funkcii dolzhna byt strogo soglasovana s informaciej o parametre funkcii vysshego poryadka v tom chisle esli eto pustoe mnozhestvo tipizaciya mehanizma obrabotki isklyuchenij nemedlenno trebuet polimorfnosti tipov samih isklyuchenij v protivnom sluchae funkcii vysshego poryadka perestayut byt polimorfnymi V to zhe vremya v bezopasnom yazyke isklyucheniya yavlyayutsya rasshiryaemoj summoj to est variantnym tipom konstruktory kotorogo dobavlyayutsya po hodu programmy Sootvetstvenno tipobezopasnost potoka isklyuchenij oznachaet neobhodimost podderzhki tipov summ kotorye yavlyayutsya odnovremenno rasshiryaemymi i polimorfnymi I zdes vnov resheniem yavlyaetsya ryadnyj polimorfizm Kak i v ischislenii Garrigi dlya polimorfnyh summ v MLPolyR ispolzuetsya specialnyj sintaksis obratnyj apostrof predvaryayushij teg i net nuzhdy v predvaritelnom obyavlenii tipa summy to est vysheprivedyonnyj kod eto vsya programma a ne fragment Preimushestvo sostoit v tom chto problemy s kontrolem polnoty razbora ne voznikaet semantika MLPolyR opredelena cherez preobrazovanie vo vnutrennij yazyk s dokazannoj nadyozhnostyu ne podderzhivayushij ni polimorfizma summ ni isklyuchenij ne govorya uzhe o nepojmannyh isklyucheniyah tak chto neobhodimost ih udaleniya na etape kompilyacii sama po sebe yavlyaetsya dokazatelstvom nadyozhnosti MLPolyR ispolzuet netrivialnoe sochetanie neskolkih ischislenij i dvuhstadijnuyu translyaciyu Dlya vyvedeniya i soglasovaniya tipov on ispolzuet ischislenie Remi odnovremenno ispolzuya princip matematicheskoj dvojstvennosti dlya predstavleniya summ kak proizvedenij dalee transliruet yazyk v promezhutochnyj yavno tipizirovannyj yazyk s polimorfnymi zapisyami i zatem ispolzuet effektivnyj sposob kompilyacii postroennyj Ohori Inache govorya model kompilyacii Ohori byla obobshena do podderzhki ischisleniya Remi Na teoretiko ti povom urovne Blyum vvodit srazu neskolko novyh sintaksicheskih notacij pozvolyayushih zapisyvat pravila dlya tipizacii isklyuchenij i pervoklassnyh vetvlenij Sistema tipov MLPolyR obespechivaet polnoe vyvedenie tipov tak chto avtory otkazalis ot razrabotki ploskogo sintaksisa dlya yavnoj zapisi tipov i ot podderzhki signatur v yazyke modulej V sisteme tipov Lejena takzhe voznikaet variant polimorfizma vetvlenij konstrukciya case mozhet byt predstavlena v vide funkcii vysshego poryadka poluchayushej zapis iz funkcij kazhdaya iz kotoryh sootvetstvuet opredelyonnoj vetvi vychislenij sintaksis Haskela podhodit dlya etogo izmeneniya i ne trebuet peresmotra Naprimer data List a nil cons hd a tl List a snoc xs r case reverse xs r last xs snoc xs nil r gt cons r gt r hd Poskolku zapisi v sisteme Lejena yavlyayutsya rasshiryaemymi razbor vetvlenij obretaet gibkost na urovne dinamicheskih reshenij naprimer cepochki proverok ili ispolzovaniya associativnogo massiva no obespechivaet gorazdo bolee effektivnuyu realizaciyu metka varianta sootvetstvuet smesheniyu v zapisi Odnako ot podderzhki vetvleniya po umolchaniyu default v dannom sluchae prihoditsya otkazatsya poskolku edinstvennyj default obrazec sootvetstvoval by mnozhestvu polej i sootvetstvenno mnozhestvu smeshenij Lejen nazyvaet etu konstrukciyu pervoklassnymi obrazcami dlya sopostavleniya first class patterns Polimorfizm v vysshih roda hPolimorfizm v vysshih roda h angl higher kinded polymorphism oznachaet abstrakciyu nad konstruktorami tipov vysshih poryadkov to est ti povymi operatorami vida gt gt gt Podderzhka etoj vozmozhnosti podnimaet polimorfizm na bolee vysokij uroven obespechivaya abstrakciyu kak nad tipami tak i nad konstruktorami tipov podobno tomu kak funkcii vysshih poryadkov obespechivayut abstrakciyu kak nad znacheniyami tak i nad drugimi funkciyami Polimorfizm v vysshih roda h yavlyaetsya estestvennym komponentom mnogih idiom funkcionalnogo programmirovaniya vklyuchaya monady svyortki i vstraivaemye yazyki Naprimer esli opredelit sleduyushuyu funkciyu yazyk Haskell when b m if b then m else return to dlya neyo budet vyveden takoj funkcionalnyj tip when forall m gt Monad m gt Bool gt m gt m Signatura m gt govorit o tom ti povaya peremennaya m yavlyaetsya peremennoj tipa prinadlezhashego k vysshemu rodu angl higher kinded type variable Eto znachit chto ona abstragiruetsya nad konstruktorami tipov v dannom sluchae unarnymi takimi kak Maybe ili kotorye mogut primenyatsya k konkretnym tipam takim kak Int ili dlya postroeniya novyh tipov V yazykah podderzhivayushih polnuyu abstrakciyu tipa Standard ML OCaml vse ti povye peremennye dolzhny prinadlezhat k rodu v protivnom sluchae sistema tipov byla by nebezopasnoj Polimorfizm v vysshih roda h takim obrazom obespechivaetsya za schyot samogo mehanizma abstrakcii v sochetanii s yavnym annotirovaniem pri instancirovanii chto neskolko neudobno Tem ne menee vozmozhna idiomaticheskaya realizaciya polimorfizma v vysshih roda h ne trebuyushaya yavnogo annotirovaniya dlya etogo na urovne tipov primenyaetsya tehnika analogichnaya defunkcionalizacii Polimorfizm rodo vSistemy rodo v angl kind systems obespechivayut bezopasnost samih sistem tipov pozvolyaya kontrolirovat smysl ti povyh vyrazhenij Naprimer pust trebuetsya realizovat vmesto obychnogo tipa vektor linejnyj massiv semejstvo tipov vektor dlinoj n inache govorya opredelit tip vektor indeksirovannyj dlinoj Klassicheskaya realizaciya na Haskell vyglyadit tak data Zero data Succ n data Vec gt gt where Nil Vec a Zero Cons a gt Vec a n gt Vec a Succ n Zdes vnachale opredelyayutsya fantomnye tipy to est tipy ne imeyushie dinamicheskogo predstavleniya Konstruktory Zero i Succ sluzhat znacheniyami sloya tipov a peremennaya n obespechivaet neravenstvo raznyh konkretnyh tipov postroennyh konstruktorom Succ Tip Vec opredelyon kak obobshyonnyj algebraicheskij tip dannyh GADT Reshenie uslovno predpolagaet chto fantomnyj tip n budet ispolzovatsya dlya modelirovaniya celochislennogo parametra vektora na osnove aksiom Peano to est budut stroitsya tolko takie vyrazheniya kak Succ Zero Succ Succ Zero Succ Succ Succ Zero i t d Odnako hotya opredeleniya zapisany na yazyke tipov sami po sebe oni sformulirovany bestipovym obrazom Eto vidno po signature Vec gt gt oznachayushej chto konkretnye tipy peredavaemye v kachestve parametrov prinadlezhat rodu a znachit mogut byt lyubym konkretnym tipom Inache govorya zdes ne zapreshayutsya bessmyslennye ti povye vyrazheniya vrode Succ Bool ili Vec Zero Int Bolee razvitoe ischislenie pozvolilo by zadat oblast znachenij parametra tipa bolee tochno data Nat Zero Succ Nat data Vec gt Nat gt where VNil Vec a Zero VCons a gt Vec a n gt Vec a Succ n No obychno takoj vyrazitelnostyu obladayut lish uzko specializirovannye sistemy s zavisimymi tipami realizovannye v takih yazykah kak Agda Coq i drugimi Naprimer s pozicii yazyka Agda zapis Vec gt Nat gt oznachala by chto rod tipa Vec zavisit ot tipa Nat to est element odnogo zavisit ot elementa drugogo bolee nizkogo V 2012 godu bylo postroeno rasshirenie yazyka Haskell realizuyushee bolee razvituyu sistemu rodo v i delayushee vysheprivedyonnyj kod korrektnym kodom na Haskell Reshenie sostoit v tom chto vse tipy za opredelyonnymi ogranicheniyami avtomaticheski prodvigayutsya angl promote na uroven vyshe formiruya odnoimyonnye roda kotorye mozhno ispolzovat yavnym obrazom S etoj tochki zreniya zapis Vec gt Nat gt ne yavlyaetsya zavisimoj ona oznachaet lish chto vtoroj parametr vektora dolzhen prinadlezhat k imenovannomu rodu Nat a v dannom sluchae edinstvennym elementom etogo roda yavlyaetsya odnoimyonnyj tip Reshenie yavlyaetsya vesma prostym kak s tochki zreniya realizacii v kompilyatore tak i s tochki zreniya prakticheskoj dostupnosti A poskolku polimorfizm tipov iznachalno yavlyaetsya estestvennym elementom semantiki Haskell prodvizhenie tipov privodit k polimorfizmu rodo v angl kind polymorphism kotoryj odnovremenno povyshaet koefficient povtornogo ispolzovaniya koda i obespechivaet bolee vysokij uroven tipobezopasnosti Naprimer sleduyushij GADT ispolzuemyj dlya verifikacii ravenstva tipov data EqRefl a b where Refl EqRefl a a v klassicheskom Haskell imeet rod gt gt chto ne pozvolyaet ispolzovat ego dlya proverki ravenstva konstruktorov tipov takih kak Maybe Sistema rodov osnovannaya na prodvizhenii tipov vyvodit polimorfnyj rod forall X X gt X gt delaya tip EqRefl bolee universalnym Eto mozhno zapisat yavno data EqRefl a X b X where Refl forall X forall a X EqRefl a aPolimorfizm effektovSistemy effektov angl effect systems byli predlozheny Giffordom i Lukassenom vo vtoroj polovine 1980 h s celyu obosobleniya pobochnyh effektov dlya bolee tonkogo kontrolya za bezopasnostyu i effektivnostyu v konkurentnom programmirovanii Polimorfizm effektov angl effect polymorphism pri etom oznachaet kvantifikaciyu nad chistotoj konkretnoj funkcii to est vklyuchenie v funkcionalnyj tip flaga harakterizuyushego funkciyu kak chistuyu libo nechistuyu Takoe rasshirenie tipizacii pozvolyaet abstragirovat chistotu funkcij vysshego poryadka ot chistoty funkcij peredavaemyh im v kachestve argumentov Eto priobretaet osoboe znachenie pri perehode k funkciyam nad modulyami zapisyami vklyuchayushimi v svoj sostav abstraktnye tipy funktoram poskolku v usloviyah chistoty oni imeyut pravo byt applikativnymi no v prisutstvii pobochnyh effektov oni obyazany byt porozhdayushimi dlya obespecheniya tipobezopasnosti podrobnee ob etom sm ekvivalentnost tipov v yazyke modulej ML Takim obrazom v yazyke modulej pervogo klassa vysshego poryadka polimorfizm effektov okazyvaetsya neobhodimoj osnovoj dlya podderzhki polimorfizma porozhdaemosti angl generativity polymorphism peredacha flaga chistoty v funktor obespechivaet vybor mezhdu applikativnoj i porozhdayushej semantikoj v edinoj sisteme Podderzhka v yazykah programmirovaniyaTipobezopasnyj parametricheskij polimorfizm dostupen v yazykah tipizirovannyh po Hindli Milneru v dialektah ML Standard ML OCaml Alice F i ih potomkah Haskell Clean Idris Mercury Agda a takzhe v nasledovannyh ot nih gibridnyh yazykah Scala Nemerle Obobshyonnye tipy dannyh dzheneriki otlichayutsya ot parametricheski polimorfnyh sistem tem chto ispolzuyut angl i potomu ne mogut imet rang vyshe 1 go Oni dostupny v Ada Eiffel Java C D Rust a takzhe v Delphi nachinaya s 2009 j versii Vpervye oni poyavilis v CLU Intensionalnyj polimorfizm Intensionalnyj polimorfizm angl intensional polymorphism predstavlyaet soboj tehniku optimiziruyushej kompilyacii parametricheskogo polimorfizma na osnove slozhnogo teoretiko ti povogo analiza kotoraya sostoit v vychisleniyah nad tipami vo vremya vypolneniya programmy Intensionalnyj polimorfizm pozvolyaet realizovyvat bestegovuyu sborku musora neobyornutuyu unboxed peredachu argumentov v funkcii i upakovannye optimizirovannye po pamyati ploskie struktury dannyh Monomorfizaciya Monomorfizaciya angl monomorphizing predstavlyaet soboj tehniku optimiziruyushej kompilyacii parametricheskogo polimorfizma kotoraya zaklyuchaetsya v porozhdenii monomorfnogo ekzemplyara dlya kazhdogo sluchaya ispolzovaniya polimorfnoj funkcii ili tipa Drugimi slovami parametricheskij polimorfizm na urovne ishodnogo koda transliruetsya v ad hoc polimorfizm na urovne celevoj platformy Monomorfizaciya povyshaet bystrodejstvie tochnee delaet polimorfizm besplatnym no vmeste s tem mozhet uvelichivat razmer vyhodnogo mashinnogo koda Hindli Milner V klassicheskom variante sistema tipov Hindli Milnera a takzhe prosto Hindli Milner ili H M angl HM polozhennaya v osnovu yazyka ML predstavlyaet soboj podmnozhestvo Sistemy F ogranichennoe predikativnym preneksnym polimorfizmom s celyu obespecheniya vozmozhnosti avtomaticheskogo vyvedeniya tipov dlya chego v sostav Hindli Milnera tradicionno takzhe vklyuchalsya tak nazyvaemyj angl razrabotannyj Robinom Milnerom Mnogie realizacii H M yavlyayutsya uluchshennoj versiej sistemy predstavlyaya soboj sistemu glavnoj tipizacii angl principal typing scheme kotoraya za odin prohod s pochti linejnoj slozhnostyu odnovremenno vyvodit naibolee obshie polimorfnye tipy dlya kazhdogo vyrazheniya i strogo proveryaet ih soglasovanie S momenta svoego poyavleniya sistema tipov Hindli Milnera byla rasshirena po neskolkim napravleniyam Odnim iz naibolee izvestnyh rasshirenij yavlyaetsya podderzhka ad hoc polimorfizma posredstvom klassov tipov dalnejshim obobsheniem kotoryh stali kvalificirovannye tipy Avtomaticheskoe vyvedenie tipov bylo sochteno neobhodimostyu pri pervonachalnoj razrabotke yazyka ML v kachestve interaktivnoj sistemy dokazatelstva teorem Logic for Computable Functions iz za chego i byli nalozheny sootvetstvuyushie ogranicheniya V dalnejshem na osnove ML byl razrabotan celyj ryad effektivno kompiliruemyh yazykov obshego naznacheniya orientirovannyh na angl a v etom sluchae neobhodimost podderzhki vyvedeniya tipov rezko snizhaetsya tak kak interfejsy modulej v promyshlennoj praktike v lyubom sluchae neobhodimo yavno annotirovat tipami Poetomu bylo predlozheno mnozhestvo variantov rasshireniya Hindli Milnera otkazyvayushihsya ot vyvedeniya tipov radi rasshireniya vozmozhnostej vplot do podderzhki polnoj Sistemy F s impredikativnym polimorfizmom takih kak yazyk modulej vysshego poryadka iznachalno osnovannyj na yavnom annotirovanii tipov modulej i imeyushij mnozhestvo rasshirenij i dialektov a takzhe rasshireniya yazyka Haskell Rank2Types RankNTypes i ImpredicativeTypes Kompilyator MLton yazyka Standard ML osushestvlyaet monomorfizaciyu no za schyot drugih primenimyh k Standard ML optimizacij rezultiruyushee uvelichenie vyhodnogo koda ne prevyshaet 30 Si i C V yazyke Si funkcii ne yavlyayutsya obektami pervogo klassa no vozmozhno opredelenie ukazatelej na funkcii chto pozvolyaet stroit funkcii vysshih poryadkov Takzhe dostupen nebezopasnyj parametricheskij polimorfizm za schyot yavnoj peredachi neobhodimyh svojstv tipa cherez bestipovoe podmnozhestvo yazyka predstavlennoe netipizirovannym ukazatelem void nazyvaemym v soobshestve yazyka obobshyonnym ukazatelem angl generic pointer Naznachenie i udalenie informacii o tipe pri privedenii tipa k void i obratno ne yavlyaetsya ad hoc polimorfizmom tak kak ne menyaet predstavlenie ukazatelya odnako ego zapisyvayut yavno dlya obhoda sistemy tipov kompilyatora Naprimer standartnaya funkciya qsort sposobna obrabatyvat massivy elementov lyubogo tipa dlya kotorogo opredelena funkciya sravneniya struct segment int start int end int seg cmpr struct segment a struct segment b return abs a gt end a gt start abs b gt end b gt start int str cmpr char a char b return strcmp a b struct segment segs 2 5 4 3 9 3 6 8 char strs three one two five four main qsort strs sizeof strs sizeof char sizeof char int void void str cmpr qsort segs sizeof segs sizeof struct segment sizeof struct segment int void void seg cmpr Tem ne menee v Si vozmozhno idiomaticheskoe vosproizvedenie tipizirovannogo parametricheskogo polimorfizma bez ispolzovaniya void Yazyk C predostavlyaet podsistemu shablonov ispolzovanie kotoryh vneshne pohozhe na parametricheskij polimorfizm no semanticheski realizuetsya sochetaniem ad hoc mehanizmov template lt typename T gt T max T x T y if x lt y return y else return x int main int a max 10 15 double f max 123 11 123 12 Monomorfizaciya pri kompilyacii shablonov C yavlyaetsya neizbezhnoj tak kak v sisteme tipov yazyka otsutstvuet podderzhka polimorfizma polimorfnyj yazyk zdes yavlyaetsya angl nadstrojkoj nad monomorfnym yadrom yazyka Eto privodit k kratnomu uvelicheniyu obyoma poluchaemogo mashinnogo koda chto poluchilo izvestnost kak razduvanie koda IstoriyaEtot razdel nuzhno dopolnit Pozhalujsta uluchshite i dopolnite razdel 12 yanvarya 2016 Notaciyu parametricheskogo polimorfizma kak razvitie lyambda ischisleniya nazvannuyu polimorfnym lyambda ischisleniem ili Sistemoj F formalno opisal logik angl 1971 god nezavisimo ot nego pohozhuyu sistemu opisal informatik angl 1974 god Vpervye parametricheskij polimorfizm byl predstavlen v yazyke ML v 1973 Nezavisimo ot nego parametricheskie tipy byli realizovany pod rukovodstvom Barbary Liskov v CLU 1974 god Sm takzheKonstruktor tipov Rod teoriya tipov angl PrimechaniyaStrachey Fundamental Concepts 1967 Pirs 2002 Cardelli Wegner On Understanding Types 1985 1 3 Kinds of Polymorphism s 6 Appel Critique of SML 1992 Jones Theory of Qualified Types 1992 Gaster Jones Polymorphic Extensible Records and Variants 1996 Cardelli Basic Polymorphic Typechecking 1987 Wonseok Chae Ph D Thesis 2009 s 91 92 Rossberg 1ML Core and Modules United F ing First class Modules 2015 Blume Exception Handlers 2008 s 11 Wells 1994 Pirs 2002 22 Rekonstrukciya tipov s 361 Pirs 2002 23 6 Stiranie tipiziruemost i rekonstrukciya tipov s 378 381 Remy ML with abstract and record types 1994 Garrigue Remy Semi Explicit First Class Polymorphism for ML 1997 Reynolds Theories of programming languages 1998 17 Polymorphism Bibliographic Notes s 393 First class polymorphism on MLton neopr Data obrasheniya 28 iyulya 2016 Arhivirovano 28 noyabrya 2015 goda Pirs 2002 22 7 Polimorfizm cherez let s 354 359 Ohori Polymorphic Record Calculus and Its Compilation 1995 Dushkin Monomorfizm polimorfizm i ekzistencialnye tipy 2010 Cardelli Typeful programming 1991 s 20 Pirs 2002 23 10 Impredikativnost s 385 Pirs 2002 Glava 22 Rekonstrukciya tipov Razdel 22 8 Dopolnitelnye zamechaniya s 361 362 Wonseok Chae Ph D Thesis 2009 s 14 Garrigue Polymorphic Variants 1998 Blume Extensible Programming with First Class Cases 2006 s 10 Ohori Polymorphic Record Calculus and Its Compilation 1995 1 1 Static Type System for Record Polymorphism s 3 6 Leijen First class Labels 2004 s 1 Gaster Jones Polymorphic Extensible Records and Variants 1996 Abstract s 1 Paulson ML for the Working Programmer 1996 2 9 Records s 35 Ohori Polymorphic Record Calculus and Its Compilation 1995 1 2 Compilation Method for Record Polymorphism s 6 8 Harper Intro to SML 1986 Remy Type Inference for Records 1991 s 2 Blume Row polymorphism at work 2007 Functional record update neopr Data obrasheniya 30 iyunya 2016 Arhivirovano 2 iyunya 2016 goda Alice ML syntactic enhancements neopr Data obrasheniya 30 iyunya 2016 Arhivirovano 27 noyabrya 2016 goda Functional record extension and row capture neopr Data obrasheniya 30 iyunya 2016 Arhivirovano 13 avgusta 2016 goda Harper Pierce Record calculus based on symmetric concatenation 1991 Wand Type inference for record concatenation and multiple inheritance 1991 Sulzmann 1997 Pirs 2002 1 4 Kratkaya istoriya s 11 13 Remy Type Inference for Records 1991 s 2 3 Leijen First class Labels 2004 s 13 14 Cardelli Semantics of Multiple Inheritance 1988 Cardelli Wegner On Understanding Types 1985 Pirs 2002 16 Metateoriya podtipov s 225 Pirs 2002 11 8 Zapisi s 135 Minski v perevode DMK 2014 Podtipizaciya i ryadnyj polimorfizm s 267 268 Wand Type inference for objects 1987 Minski v perevode DMK 2014 Polimorfizm obektov s 255 257 Remy Type Inference for Records 1991 Related work s 3 Remy Type Inference for Records 1991 Blume Extensible Programming with First Class Cases 2006 s 11 Remy Subtypes and Row polymorphism 1995 Remy Vouillon Objective ML 1998 Pirs 2002 15 8 Dopolnitelnye zamechaniya s 223 Minski v perevode DMK 2014 Polimorfnye varianty s 149 158 Pirs 2002 24 Ekzistencialnye tipy p 404 Reynolds Theories of programming languages 1998 18 Module Specification s 401 410 Cardelli Typeful programming 1991 4 4 Tuple types s 20 23 Harper Lillibridge Type Theoretic Approach to Higher Order Modules with Sharing 1993 Yallop White Lightweight higher kinded polymorphism 2014 Harper Mitchell Type Structure of SML 1993 Rossberg 1ML Core and Modules United F ing First class Modules 2015 Impredicativity Reloaded s 6 Rossberg 1ML with Special Effects F ing Generativity Polymorphism 2016 Ohori Compilation Method for Polymorphic Record Calculi 1992 Ohori SML presentation neopr Data obrasheniya 30 iyunya 2016 Arhivirovano iz originala 27 avgusta 2016 goda Ohori Polymorphic Record Calculus and Its Compilation 1995 s 38 Blume Extensible Programming with First Class Cases 2006 s 9 Ohori Polymorphic Record Calculus and Its Compilation 1995 5 Implementaion s 37 Blume Extensible Programming with First Class Cases 2006 Gaster Ph D Thesis 1998 Leijen First class Labels 2004 s 7 Leijen First class Labels 2004 Extensible records on Haskell Wiki nedostupnaya ssylka Blume personal page neopr Data obrasheniya 30 iyunya 2016 Arhivirovano 19 maya 2016 goda Blume Exception Handlers 2008 Wonseok Chae Ph D Thesis 2009 Paulson ML for the Working Programmer 1996 4 6 Declaring exceptions s 135 Harper Practical Foundations for Programming Languages 2012 28 3 Exception Type s 258 260 ML2000 Preliminary Design 1999 Harper Practical Foundations for Programming Languages 2012 Chapter 22 Constructors and Kinds s 193 Weirich et al Giving Haskell a promotion 2012 Fluet Pucella Phantom Types and Subtyping 2006 Pirs 2002 30 5 Idem dalshe zavisimye tipy s 489 490 Gifford Lucassen Effect systems 1986 Lucassen Gifford Polymorphic Effect Systems 1988 Talpin Jouvelot 1992 Harper Morrisett Intensional Type Analysis 1995 Crary Weirich Morrisett Intensional polymorphism 1998 Pirs 2002 23 2 Raznovidnosti polimorfizma s 364 365 Weeks Whole Program Compilation in MLton 2006 Hindley Principal Type Scheme 1969 Milner Theory of Type Polymorphism 1978 Jones FP with Overloading and H O Polymorphism 1995 Kernigan B Ritchi D Yazyk programmirovaniya Si The C programming language 2 e izd 2007 S 304 ISBN 0 13 110362 8 Glava 5 11 Ukazateli na funkcii Appel Critique of SML 1992 s 5 Oleg Kiselyov Truly polymorphic lists in C neopr okmij org Data obrasheniya 22 noyabrya 2016 Arhivirovano 30 yanvarya 2017 goda Mitchell Concepts in Programming Languages 2004 6 4 Polymorphism and overloading s 145 151 Scott Meyers Code Bloat due to Templates neopr comp lang c moderated Usenet 16 maya 2002 Data obrasheniya 19 yanvarya 2010 Girard Extension of Type Theory 1971 Girard Higher order calculus 1972 Reynolds Theory of Type Structure 1974 Pirs 2002 23 3 Sistema F s 365 366 Milner et al LCF 1975 LiteraturaChristopher Strachey Fundamental Concepts in Programming Languages 1967 Arhivirovano 12 avgusta 2017 goda Povtorno opublikovano Christopher Strachey Fundamental Concepts in Programming Languages 2000 T 13 S 11 49 doi 10 1023 A 1010000313106 J Roger Hindley The principal type scheme of an object in combinatory logic angl Transactions of the American Mathematical Society American Mathematical Society 1969 Vol 146 P 29 60 doi 10 2307 1995158 Jean Yves Girard Une Extension de l Interpretation de Godel a l Analyse et son Application a l Elimination des Coupures dans l Analyse et la Theorie des Types fr Proceedings of the Second Scandinavian Logic Symposium Amsterdam 1971 P 63 92 doi 10 1016 S0049 237X 08 70843 7 Jean Yves Girard Interpretation fonctionnelle et elimination des coupures de l arithmetique d ordre superieur fr Universite Paris 7 1972 John C Reynolds Towards a Theory of Type Structure Paris Colloque sur la programmation 1974 T 19 S 408 425 doi 10 1007 3 540 06859 7 148 Milner R Morris L Newey M A Logic for Computable Functions with reflexive and polymorphic types Arc et Senans Proc Conference on Proving and Improving Programs 1975 Robin Milner A Theory of Type Polymorphism in Programming angl 1978 T 17 vyp 3 S 348 375 doi 10 1016 0022 0000 78 90014 4 angl John S Mitchell Operations on Records Mathematical Structures in Computer Science 1991 T 1 vyp 1 angl Peter Wegner On Understanding Types Data Abstraction and Polymorphism New York USA ACM 1985 T 17 vyp 4 S 471 523 ISSN 0360 0300 doi 10 1145 6041 6042 angl Vvedenie v Standartnyj ML rus Carnegie Mellon University 1986 97 s ISBN PA 15213 3891 John M Lucassen David K Gifford Integrating Functional and Imperative Programming 1986 angl Basic Polymorphic Typechecking 1987 angl Complete Type Inference for Simple Objects angl In Proc 2nd IEEE Symposium on Logic in Computer Science 1987 P 37 44 Martin Abadi angl Pierre Louis Curien Formal Parametric Polymorphism POPL 1993 angl A Semantics of Multiple Inheritance angl Inf Comput 76 1988 P 138 164 John M Lucassen David K Gifford Polymorphic Effect Systems 1988 Didier Remy Type Inference for Records in a natural Extension of ML Research Report 1431 Institut National de Recherche en Informatique et Automatisme 1991 angl Typeful programming angl IFIP State of the Art Reports New York Springer Verlag 1991 Iss Formal Description of Programming Concepts P 431 507 angl Benjamin Pierce Record calculus based on symmetric concatenation CMU CS 90 157R Carnegie Mellon University supported and monitored by Naval Research 1991 angl Type inference for record concatenation and multiple inheritance Selections from 1989 IEEE Symposium on Logic in Computer Science Information and Computation 1991 T 93 vyp 1 doi 10 1016 0890 5401 91 90050 C Andrew W Appel A Critique of Standard ML Princeton University 1992 Mark P Jones A Theory of Qualified Types ESOP Springer Verlag Lecture Notes in Computer Science 1992 Atsushi Ohori A Compilation Method for ML Style Polymorphic Record Calculi POPL Proceedings of the 19th ACM SIGPLAN SIGACT symposium on Principles of programming languages Kyoto University ACM 1992 S 154 165 doi 10 1 1 105 7655 J P Talpin P Jouvelot Polymorphic Type Region and Effect Inference 2 3 245271 1992 angl John S Mitchell On The Type Structure of Standard ML ACM TOPLAS 1993 S 211 252 angl Mark Lillibridge Type Theoretic Approach to Higher Order Modules with Sharing angl ACM Press 1993 ISBN CMU CS 93 197 doi 10 1 1 14 3595 Didier Remy Programming objects with ML ART An extension to ML with abstract and record types International Symposium on Theoretical Aspects of Computer Software Springer Verlag 1994 S 321 346 J B Wells Typability and Type Checking in the Second Order Lambda Calculus are Equivalent and Undecidable angl Proceedings of the 9th Annual IEEE Symposium on Logic in Computer Science LICS 1994 P 176 185 angl Compiling Polymorphism Using Intensional Type Analysis 1995 Atsushi Ohori A Polymorphic Record Calculus and Its Compilation Kyoto University ACM 1995 S 844 895 Mark P Jones Functional Programming with Overloading and Higher Order Polymorphism Springer Verlag Lecture Notes 1995 doi 10 1 1 26 9460 Didier Remy Better Subtypes and Row Variables for Record Types Presented at the workshop on Advances in types for computer science at the Newton Institute Cambridge UK 1995 angl ML for the Working Programmer 2nd Cambridge Great Britain Cambridge University Press 1996 492 s ISBN 0 521 57050 6 hardback 0 521 56543 X paperback Benedict R Gaster Mark P Jones A Polymorphic Type System for Extensible Records and Variants Technical Report NOTTCS TR 96 3 University of Nottingham 1996 Jacques Garrigue Didier Remy Semi Explicit First Class Polymorphism for ML Academic Press Information and Computation 1997 M Sulzmann Designing Record Systems Technical Report YALEU DCS RR 1128 Yale University 1997 doi 10 1 1 17 6563 Karl Crary Stephanie Weirich J Gregory Morrisett Intensional polymorphism in type erasure semantics 1998 Benedict R Gaster Records variants and qualified types Technical report NOTTCS TR 98 3 Ph D Thesis 1998 Jacques Garrigue Programming with Polymorphic Variants Kyoto University 1998 Didier Remy Jerome Vouillon Objective ML An effective object oriented extension to ML Theory And Practice of Object Systems ACM 1998 T 4 1 S 27 50 John C Reynolds Theories of programming languages Cambridge University Press 1998 ISBN 978 0 521 59414 1 hardback 978 0 521 10697 9 paperback The ML2000 Working Group Principles and a Preliminary Design for ML2000 angl 1999 Benjamin Pierce Types and Programming Languages MIT Press 2002 ISBN 0 262 16209 1 Perevod na russkij yazyk Bendzhamin Pirs Tipy v yazykah programmirovaniya 2012 680 s ISBN 978 5 7913 0082 9 John C Mitchell Concepts in Programming Languages Cambridge University Press 2004 ISBN 0 511 04091 1 eBook in netLibrary 0 521 78098 5 hardback Jens Palsberg Tian Zhao Type Inference for Record Concatenation and Subtyping 2004 Arhivirovano 16 sentyabrya 2016 goda Daan Leijen First class Labels for Extensible Rows TechReport UU CS 2004 51 Universiteit Utrecht 2004 Matthias Blume Umut A Acar Wonseok Chae Extensible Programming with First Class Cases 2006 Matthew Fluet Riccardo Pucella Phantom Types and Subtyping angl 2006 Stephen Weeks Whole Program Compilation in MLton angl 2006 Arhivirovano 29 iyunya 2007 goda Matthias Blume Records Sums Cases and Exceptions Row polymorphism at work speech video Microsoft 2007 Matthias Blume Umut A Acar Wonseok Chae Exception Handlers as Extensible Cases Toyota Technological Institute at Chicago APLAS 2008 Wonseok Chae Type Safe Extensible Programming Ph D Thesis Toyota Technological Institute at Chicago 2009 Roman Dushkin Monomorfizm polimorfizm i ekzistencialnye tipy 2010 Jeremy Yallop Leo White Lightweight higher kinded polymorphism International Symposium on Functional and Logic Programming 2014 angl Practical Foundations for Programming Languages version 1 37 revised 01 11 2014 licensed under the Creative Commons Attribution Noncommercial No Derivative Works 3 0 United States License 2012 544 s Arhivnaya kopiya ot 24 oktyabrya 2015 na Wayback MachineStephanie Weirich Brent A Yorgey Julien Cretin Simon Peyton Jones Dimitrios Vytiniotis and Jose P Magalhaes Giving Haskell a promotion In Proceedings of the 8th ACM SIGPLAN Workshop on Types in Language Design and Implementation NY USA 2012 S 53 66 Minsky Madhavapeddy Hickey Real World OCaml Functional Programming for the Masses angl O Reilly Media 2013 510 p ISBN 9781449324766 Perevod na russkij yazyk Minski Madhavapeddi Hikki Programmirovanie na yazyke OCaml rus DMK 2014 536 s ISBN 978 5 97060 102 0 Andreas Rossberg 1ML Core and Modules United F ing First class Modules 2015 Andreas Rossberg 1ML with Special Effects F ing Generativity Polymorphism WadlerFest Google 2016 Haskell Wiki Existential types neopr Haskell Wiki Rank N types neopr Haskell Wiki Impredicative types neopr Jacques Garrigue OCaml manual Polymorphic variants neopr

NiNa.Az

NiNa.Az - Абсолютно бесплатная система, которая делится для вас информацией и контентом 24 часа в сутки.
Взгляните
Закрыто