Система типов Хиндли – Милнера
этой статьи Начальный раздел может быть слишком коротким, чтобы адекватно суммировать ключевые моменты . ( март 2024 г. ) |
Хиндли -Милнера ( HM ) Система типов — это классическая система типов для лямбда-исчисления с параметрическим полиморфизмом . Он также известен как Дамас-Милнер или Дамас-Хиндли-Милнер . Впервые его описал Дж. Роджер Хиндли. [1] и позже вновь открыт Робином Милнером . [2] Луис Дамас представил тщательный формальный анализ и доказательство метода в своей докторской диссертации. [3] [4]
Среди наиболее примечательных свойств HM — его полнота и способность определять наиболее общий тип данной программы без аннотаций типов или других подсказок, предоставляемых программистом. Алгоритм W является эффективным методом вывода типов на практике и успешно применяется на больших базах кода, хотя и имеет высокую теоретическую сложность . [примечание 1] HM предпочтительно используется для функциональных языков . Впервые он был реализован как часть системы типов языка программирования ML . С тех пор HM расширялся различными способами, в первую очередь за счет классов типов, ограничений подобных тем, что есть в Haskell .
Введение
[ редактировать ]В качестве метода вывода типа Хиндли-Милнер может выводить типы переменных, выражений и функций из программ, написанных в совершенно нетипизированном стиле. Будучи чувствительным к области действия , он не ограничивается получением типов только из небольшой части исходного кода, а скорее из целых программ или модулей. Способность работать с параметрическими типами также является основой систем типов многих функциональных языков программирования . Впервые он был применен таким образом в языке программирования ML .
Происхождением является алгоритм вывода типа для просто типизированного лямбда-исчисления , который был разработан Хаскеллом Карри и Робертом Фейсом в 1958 году. [ нужна ссылка ] В 1969 году Дж. Роджер Хиндли расширил эту работу и доказал, что их алгоритм всегда выводит наиболее общий тип. В 1978 году Робин Милнер [5] независимо от работы Хиндли предоставил эквивалентный алгоритм, алгоритм W. в 1982 году. Луис Дамас [4] наконец доказал, что алгоритм Милнера является полным, и расширил его для поддержки систем с полиморфными ссылками.
Мономорфизм против полиморфизма
[ редактировать ]В просто типизированном лямбда-исчислении типы T являются либо константами атомарного типа, либо функциональными типами формы . Такие типы мономорфны . Типичными примерами являются типы, используемые в арифметических значениях:
3 : Number add 3 4 : Number add : Number -> Number -> Number
В отличие от этого, нетипизированное лямбда-исчисление вообще нейтрально к типизации, и многие из его функций могут быть осмысленно применены ко всем типам аргументов. Тривиальным примером является тождественная функция
- идентификатор ≡ λ Икс . х
который просто возвращает любое значение, к которому оно применено. Менее тривиальные примеры включают параметрические типы, такие как списки .
Хотя полиморфизм в целом означает, что операции принимают значения более чем одного типа, используемый здесь полиморфизм является параметрическим. В литературе также встречаются обозначения схем типов , подчеркивающие параметрическую природу полиморфизма. Кроме того, константы могут быть типизированы с помощью переменных (квантифицированного) типа. Например:
cons : forall a . a -> List a -> List a nil : forall a . List a id : forall a . a -> a
Полиморфные типы могут стать мономорфными путем последовательной замены их переменных. Примеры мономорфных экземпляров :
id' : String -> String nil' : List Number
В более общем смысле, типы являются полиморфными, если они содержат переменные типа, тогда как типы без них являются мономорфными.
В отличие от систем типов, используемых, например, в Pascal (1970) или C (1972), которые поддерживают только мономорфные типы, HM разработан с упором на параметрический полиморфизм. Преемники упомянутых языков, такие как C++ (1985), сосредоточились на различных типах полиморфизма, а именно на подтипировании в связи с объектно-ориентированным программированием и перегрузке . Хотя подтипирование несовместимо с HM, вариант систематической перегрузки доступен в основанной на HM системе типов Haskell.
Let-полиморфизм
[ редактировать ]При расширении вывода типа для просто-типизированного лямбда-исчисления в сторону полиморфизма необходимо определить, когда допустимо получение экземпляра значения. В идеале это должно быть разрешено при любом использовании связанной переменной, например:
(λ id . ... (id 3) ... (id "text") ... ) (λ x . x)
К сожалению, вывод типа в полиморфном лямбда-исчислении неразрешим. [6] Вместо этого HM предоставляет let-полиморфизм формы
let id = λ x . x in ... (id 3) ... (id "text") ...
ограничение механизма привязки в расширении синтаксиса выражений. Только значения, связанные в конструкции let, подлежат созданию экземпляров, т.е. являются полиморфными, тогда как параметры в лямбда-абстракциях рассматриваются как мономорфные.
Обзор
[ редактировать ]Оставшаяся часть этой статьи продолжается следующим образом:
- Определена система типов HM. Это делается путем описания системы вывода, которая точно определяет, какие выражения имеют какой тип, если таковые имеются.
- Далее он работает над реализацией метода вывода типа. После введения синтаксически-ориентированного варианта вышеупомянутой дедуктивной системы приводится набросок эффективной реализации (алгоритма J), апеллирующей главным образом к металогической интуиции читателя.
- Поскольку остается открытым вопрос, действительно ли алгоритм J реализует исходную систему вывода, вводится менее эффективная реализация (алгоритм W) и намекается на ее использование в доказательстве.
- Наконец, обсуждаются дополнительные темы, связанные с алгоритмом.
Одно и то же описание системы вывода используется повсюду, даже для двух алгоритмов, чтобы сделать различные формы, в которых представлен метод HM, непосредственно сопоставимыми.
Система типов Хиндли – Милнера
[ редактировать ]Система типов может быть формально описана синтаксическими правилами , которые фиксируют язык для выражений, типов и т. д. Представление здесь такого синтаксиса не слишком формально, поскольку оно написано не для изучения поверхностной грамматики , а, скорее, для изучения поверхностной грамматики. глубинная грамматика и оставляет открытыми некоторые синтаксические детали. Такая форма изложения является обычной. Основываясь на этом, правила типизации используются для определения того, как связаны выражения и типы. Как и раньше, используемая форма немного либеральна.
Синтаксис
[ редактировать ]Выражения |
Типы |
Контекст и типизация |
Переменные свободного типа |
Выражения, которые необходимо ввести, в точности соответствуют выражениям лямбда-исчисления, расширенному с помощью let-выражения, как показано в соседней таблице. Круглые скобки можно использовать для устранения неоднозначности выражения. Приложение имеет левую привязку и привязывается сильнее, чем абстракция или конструкция let-in.
Типы синтаксически делятся на две группы: монотипии и политипы. [примечание 2]
Монотипии
[ редактировать ]Монотипии всегда обозначают определенный тип. Монотипии синтаксически представлены в виде терминов .
Примеры монотипий включают константы типа, такие как или и параметрические типы, такие как . Последние типы являются примерами применения , функций типа например, из множества , где верхний индекс указывает количество параметров типа. Полный набор типовых функций произвольно в HM, [примечание 3] за исключением того, что он должен содержать как минимум , тип функции. Для удобства его часто записывают в инфиксной записи. Например, функция, отображающая целые числа в строки, имеет тип . Опять же, круглые скобки могут использоваться для устранения неоднозначности выражения типа. Приложение привязывается сильнее, чем инфиксная стрелка, которая привязывается вправо.
Переменные типа допускаются как монотипы. Монотипии не следует путать с мономорфными типами, которые исключают переменные и допускают только основные термины.
Две монотипии равны, если у них одинаковые термины.
Политипы
[ редактировать ]Политипы (или схемы типов ) — это типы, содержащие переменные, связанные нулем или более кванторами для всех, например .
Функция с политипом может сопоставить любое значение того же типа с самим собой, и функция идентификации является значением для этого типа.
В качестве другого примера: — это тип функции, отображающей все конечные множества в целые числа. Функция, возвращающая мощность набора, будет значением этого типа.
Квантификаторы могут отображаться только на верхнем уровне. Например, тип исключается синтаксисом типов. Также в состав политипов входят монотипии, при этом тип имеет общий вид. , где является монотипией.
Равенство политипов сводится к изменению порядка количественной оценки и переименованию количественных переменных ( -конверсия). Кроме того, количественные переменные, не встречающиеся в монотипе, могут быть опущены.
Контекст и типизация
[ редактировать ]Чтобы осмысленно объединить все еще разрозненные части (синтаксические выражения и типы), необходима третья часть: контекст. Синтаксически контекст представляет собой список пар , называемые присваиваниями , предположениями или привязками , каждая пара указывает это значение переменной имеет тип Все три части вместе дают типичную оценку формы. , заявив, что при предположениях , выражение имеет тип .
Переменные свободного типа
[ редактировать ]В типе , символ является квантором, связывающим переменные типа в монотипии . Переменные называются количественными , и любое появление переменной количественного типа в называется связанным , а все переменные несвязанного типа в называются бесплатными . Дополнительно к количественной оценке в политипах переменные типа также могут быть связаны, встречаясь в контексте, но с обратным эффектом в правой части . Такие переменные тогда ведут себя там как константы типа. Наконец, переменная типа может легально встречаться несвязанной при типизации, и в этом случае они неявно всеквантифицируются.
Наличие как связанных, так и несвязанных переменных типов довольно редко встречается в языках программирования. Часто все переменные типа неявно рассматриваются как всеквантованные. нет предложений со свободными переменными Например, в Прологе . Аналогично в Хаскеле [примечание 4] где все переменные типа неявно имеют количественную оценку, т.е. тип Haskell. a -> a
означает здесь. Связанным с этим, но также очень редким, является связывающий эффект правой части. из заданий.
Обычно смесь связанных и несвязанных переменных типа возникает из-за использования свободных переменных в выражении. Постоянная функция K = приводит пример. Имеет монотипию . Можно вызвать полиморфизм с помощью . Здесь, имеет тип . Свободная переменная монотипии происходит от типа переменной связанный с окружающей областью. имеет тип . Можно представить себе переменную свободного типа в типе быть связанным в типе . Но такое масштабирование не может быть выражено в HM. Скорее, привязка реализуется контекстом.
Тип заказа
[ редактировать ]Полиморфизм означает, что одно и то же выражение может иметь (возможно, бесконечно) множество типов. Но в этой системе типов эти типы не совсем не связаны друг с другом, а скорее управляются параметрическим полиморфизмом.
Например, тождество может иметь как его тип, так и или и многие другие, но не . Самый общий тип этой функции: , в то время как другие более конкретны и могут быть выведены из общего путем последовательного замена другого типа параметра типа , т. е. количественного переменная . Контрпример неверен, поскольку замена не соответствует.
Непротиворечивую замену можно сделать формальной, применив замену к термину типа , написано . Как следует из примера, замена тесно связана не только с порядком, который выражает, что тип является более или менее особенным, но также и с все-количественной оценкой, которая позволяет применить замену.
Правило специализации |
Формально в HM тип является более общим, чем , формально , если некоторая количественная переменная в последовательно заменяется так, что получается как показано на боковой панели. Этот порядок является частью определения типа системы типов.
В нашем предыдущем примере, применяя замену приведет к .
В то время как замена количественной переменной мономорфным (основным) типом является Прямо говоря, замена политипа имеет некоторые подводные камни, вызванные наличие свободных переменных. В частности, несвязанные переменные не должны быть заменил. Здесь они рассматриваются как константы. Кроме того, количественные оценки могут выполняться только на верхнем уровне. Подставляя параметрический тип, необходимо поднять его кванторы. Таблица справа уточняет это правило.
Альтернативно, рассмотрите эквивалентное обозначение для политипов без кванторы, в которых количественные переменные представлены различным набором символы. В таких обозначениях специализация сводится к простому согласованному замена таких переменных.
Отношение это частичный заказ и является его наименьшим элементом.
Основной тип
[ редактировать ]Хотя специализация схемы типов является одним из видов использования порядка, она играет важную роль. решающую вторую роль в системе типов. Вывод типа с помощью полиморфизма сталкивается с проблемой суммирования всех возможных типов, которые может иметь выражение. Приказ гарантирует существование такого резюме как наиболее общего типа. выражения.
Подстановка в типизациях
[ редактировать ]Определенный выше порядок типов можно распространить на типизации, поскольку подразумеваемая всеколичественная оценка типизаций обеспечивает последовательную замену:
В отличие от правила специализации, это не часть определения, а, как и неявная всеквантификация, скорее следствие правил типов, определенных далее. Переменные свободного типа при типизации служат заполнителями для возможных уточнений. Эффект привязки среды к свободному типу переменные в правой части запрещающее их замену в правиле специализации, снова что замена должна быть последовательной и включать всю типизацию.
В этой статье будут обсуждаться четыре различных набора правил:
- декларативная система
- синтаксическая система
- алгоритм J
- алгоритм W
Дедуктивная система
[ редактировать ]Синтаксис правил |
Синтаксис HM переносится в синтаксис правил вывода , которые образуют тело формальной системы , посредством использования типизаций в качестве суждений . Каждое из правил определяет, какой вывод из каких предпосылок можно сделать. Помимо судебных решений в качестве предпосылок могут быть использованы и некоторые дополнительные условия, представленные выше.
Доказательство с использованием правил — это последовательность суждений, в которой все предпосылки перечисляются перед заключением. В примерах ниже показан возможный формат доказательств. Слева направо в каждой строке показано заключение, применяемого правила и посылок, либо путем ссылки на более раннюю строку (номер), если посылка является суждением, либо путем явного определения предиката.
Правила набора текста
[ редактировать ]- См. также Правила набора текста.
Декларативная система правил |
В боковой рамке показаны правила вычетов системы типа HM. Условно правила можно разделить на две группы:
Первые четыре правила (доступ к переменной или функции), ( приложение , т.е. вызов функции с одним параметром), ( абстракция , т.е. объявление функции) и (объявление переменной) сосредоточены вокруг синтаксиса, представляя одно правило для каждой формы выражения. Их смысл очевиден на первый взгляд, поскольку они разлагают каждое выражение, доказывают свои подвыражения и, наконец, соединяют отдельные типы, встречающиеся в посылках, с типом в заключении.
Вторую группу образуют оставшиеся два правила. и . Они занимаются специализацией и обобщением типов. В то время как правило должно быть ясно из раздела о специализации выше , дополняет первое, работая в противоположном направлении. Он допускает обобщение, т.е. количественную оценку монотипных переменных, не связанных с контекстом.
Следующие два примера демонстрируют систему правил в действии. Поскольку и выражение, и тип заданы, они представляют собой использование правил для проверки типов.
Пример : Доказательство где , можно было бы написать
Пример : Чтобы продемонстрировать обобщение, показано ниже:
Let-полиморфизм
[ редактировать ]Не видимый сразу набор правил кодирует положение, при котором тип может быть обобщен или нет путем незначительного изменения использования моно- и политипов в правилах. и . Помните, что и обозначают поли- и монотипии соответственно.
В правиле , переменная значения параметра функции добавляется в контекст с мономорфным типом через посылку , в то время как в правиле , переменная попадает в среду в полиморфном виде . Хотя в обоих случаях наличие в контексте запрещает использование правила обобщения для любой свободной переменной в присваивании, это правило принудительно определяет тип параметра в -выражение останется мономорфным, в то время как в let-выражении переменная может быть введена полиморфной, что делает возможной специализацию.
В результате этого регулирования невозможно напечатать, поскольку параметр находится в мономорфном положении, а имеет тип , потому что был введен в let-выражение и поэтому считается полиморфным.
Правило обобщения
[ редактировать ]Правило обобщения также заслуживает более пристального внимания. Здесь всеколичественная оценка, подразумеваемая в предпосылке просто перемещается в правую часть в заключении, связанном явным квантором универсальности. Это возможно, поскольку не встречается свободно в контексте. Опять же, хотя это и делает правило обобщения правдоподобным, на самом деле оно не является его следствием. Напротив, правило обобщения является частью определения системы типов HM, а неявная всеквантификация является следствием.
Алгоритм вывода
[ редактировать ]Теперь, когда система вывода HM под рукой, можно представить алгоритм и проверить его на соответствие правилам. В качестве альтернативы его можно было бы получить, внимательно рассмотрев взаимодействие правил и способы доказательства. сформировался. Это делается в оставшейся части статьи с упором на возможные решения, которые можно принять при доказательстве типизации.
Степени свободы выбора правил
[ редактировать ]Выделение точек в доказательстве, где решение вообще невозможно, первая группа правил, основанная на синтаксисе, не оставляет выбора, поскольку каждому синтаксическому правилу соответствует уникальное правило типизации, определяющее часть доказательства, тогда как между выводом и посылками этих фиксированные части цепей и могло произойти. Такая цепочка могла существовать и между заключением доказательство и правило высшего выражения. Все доказательства должны иметь такая нарисованная форма.
Поскольку единственным выбором в доказательстве в отношении выбора правил является и цепи, Форма доказательства наводит на вопрос, можно ли его уточнить, где эти цепи могут быть не нужны. На самом деле это возможно и приводит к вариант системы правил без таких правил.
Система правил, управляемая синтаксисом
[ редактировать ]Синтаксическая система правил |
Обобщение |
Современная трактовка HM использует чисто синтаксическую систему правил из-за Клемент [7] как промежуточный этап. В этой системе специализация располагается сразу после исходной. правило и сливается с ним, а обобщение становится частью правило. Там такое обобщение также решил всегда создавать наиболее общий тип, вводя функцию , что количественно определяет все переменные монотипа, не связанные в .
Формально, чтобы подтвердить, что эта новая система правил эквивалентно оригиналу , у одного есть чтобы показать это , которое распадается на два поддоказательства:
- ( Последовательность )
- ( Полнота )
Хотя последовательность можно увидеть, разложив правила и из в доказательства в , вероятно, видно, что является неполным, так как нельзя показать в например, но только . Доказуема лишь немного более слабая версия полноты. [8] хотя, а именно
подразумевая, что можно получить основной тип выражения в что позволяет нам в конечном итоге обобщить доказательство.
Сравнивая и , сейчас в суждениях всех правил фигурируют только монотипии. Кроме того, форма любого возможного доказательства с помощью системы вывода теперь идентична форме выражения (оба рассматриваются как деревья ). Таким образом, выражение полностью определяет форму доказательства. В форма, вероятно, будет определена с учетом всех правил, кроме и , которые позволяют строить сколь угодно длинные ветки (цепочки) между остальными узлами.
Степени свободы, реализующие правила
[ редактировать ]Теперь, когда форма доказательства известна, мы уже близки к формулировке алгоритма вывода типа. Поскольку любое доказательство данного выражения должно иметь одинаковую форму, можно предположить монотипии в докажите, что суждения доказательства неопределенны, и подумайте, как их определить.
Здесь вступает в силу порядок замещения (специализации). Хотя на первый взгляд невозможно определить типы локально, есть надежда, что их можно будет уточнить с помощью порядка при обходе дерева доказательства, дополнительно предполагая, поскольку полученный алгоритм должен стать методом вывода, что Тип любого помещения будет определен как наилучший. И действительно, можно, глядя на правила предлагает:
- [ Abs ] : Критическим выбором является τ . ничего не известно На данный момент о τ , поэтому можно лишь предположить наиболее общий тип, а именно: . План состоит в том, чтобы специализировать этот тип, если в этом возникнет необходимость. К сожалению, политип в этом месте не разрешен, поэтому некоторого α на данный момент достаточно . Чтобы избежать нежелательного захвата, безопасным выбором будет переменная типа, которая еще не проверена. Кроме того, следует иметь в виду, что эта монотипия еще не фиксирована и может быть уточнена.
- [ Var ] : Выбор в том, как уточнить σ . Поскольку любой выбор типа τ здесь зависит от использования переменной, которая не известна локально, самым безопасным вариантом является наиболее общий. Используя тот же метод, что и выше, можно создать экземпляры всех количественных переменных в σ с новыми переменными монотипа, снова оставляя их открытыми для дальнейшего уточнения.
- [ Let ] : Правило не оставляет выбора. Сделанный.
- [ Приложение ] : Только правило приложения может привести к уточнению переменных, «открытых» на данный момент, как того требуют обе предпосылки.
- Первая посылка заставляет результат вывода иметь форму .
- Если это так, то хорошо. Позже можно выбрать его τ' для результата.
- Если нет, то это может быть открытая переменная. Затем это можно уточнить до требуемой формы с двумя новыми переменными, как и раньше.
- В противном случае проверка типа не удалась, поскольку первая предпосылка вывела тип, который не является и не может быть преобразован в тип функции.
- Вторая посылка требует, чтобы выведенный тип был равен τ первой посылки. Теперь есть два, возможно, разных типа, возможно, с переменными открытого типа, которые можно сравнить и приравнять, если это возможно. Если да, то обнаруживается уточнение, а если нет, то снова обнаруживается ошибка типа. Известен эффективный метод «приведения двух членов равными» заменой — Робинсона Унификация в сочетании с так называемым алгоритмом Union-Find . [ нужна ссылка ]
- Первая посылка заставляет результат вывода иметь форму .
Кратко суммируя алгоритм поиска объединения, учитывая множество всех типов в доказательстве, он позволяет группировать их в классы эквивалентности с помощью союз процедуры и выбрать представителя для каждого такого класса, используя найти процедуру. Подчеркивая слово процедура в смысле побочного эффекта , мы явно выходим из области логики, чтобы подготовить эффективный алгоритм. Представитель а. определяется так, что, если и a, и b являются переменными типа, то представителем произвольно является один из них, но при объединении переменной и термина представитель становится представителем. Предполагая реализацию Union-Find под рукой, можно сформулировать объединение двух монотипий следующим образом:
unify(ta, tb): ta = find(ta) tb = find(tb) if both ta,tb are terms of the form D p1..pn with identical D,n then unify(ta[i], tb[i]) for each corresponding ith parameter else if at least one of ta,tb is a type variable then union(ta, tb) else error 'types do not match'
Теперь, имея под рукой набросок алгоритма вывода, в следующем разделе будет дано более формальное представление. Это описано у Милнера. [2] стр. 370 и далее. как алгоритм Дж.
Алгоритм J
[ редактировать ]Алгоритм J |
Представление алгоритма J представляет собой неправильное использование обозначений логических правил, поскольку оно включает в себя побочные эффекты, но допускает прямое сравнение с одновременно выражая эффективную реализацию. В правилах теперь указана процедура с параметрами уступчивость в заключении, где исполнение посылок идет слева направо.
Процедура специализируется на политипе путем копирования термина и последовательной замены переменных связанного типа новыми переменными монотипа. ' ' создает новую переменную монотипа. Вероятный, должен скопировать тип, вводя новые переменные для количественного анализа, чтобы избежать нежелательного захвата. В целом, алгоритм теперь всегда делает наиболее общий выбор, оставляя специализацию унификации, которая сама по себе дает наиболее общий результат. Как уже отмечалось выше , окончательный результат должен быть обобщен до в конце концов, чтобы получить наиболее общий тип для данного выражения.
Поскольку стоимость процедур, используемых в алгоритме, составляет около O(1), общая стоимость алгоритма близка к линейной зависимости от размера выражения, для которого необходимо определить тип. Это резко контрастирует со многими другими попытками разработать алгоритмы вывода типа, которые часто оказывались NP-трудными , если не неразрешимыми в отношении завершения. Таким образом, HM работает так же хорошо, как и лучшие полностью информированные алгоритмы проверки типов. Проверка типов здесь означает, что алгоритму не нужно находить доказательство, а только проверять заданное.
Эффективность немного снижается, поскольку необходимо поддерживать привязку переменных типа в контексте, чтобы обеспечить возможность вычисления и включите проверку возникновения , чтобы предотвратить построение рекурсивных типов во время . Примером такого случая является , для которого тип не может быть получен с помощью HM. На практике типы представляют собой лишь небольшие термины и не образуют расширяющихся структур. Таким образом, при анализе сложности их сравнение можно рассматривать как константу, сохраняя затраты O(1).
Доказательство алгоритма
[ редактировать ]В предыдущем разделе при наброске алгоритма на его доказательство намекали с помощью металогической аргументации. Хотя это приводит к эффективному алгоритму J, неясно, правильно ли он отражает системы вывода D или S, которые служат семантической базовой линией.
Наиболее важным моментом в приведенной выше аргументации является уточнение монотипии. переменные, связанные контекстом. Например, алгоритм смело меняет контекст при выводе, например , потому что переменная монотипии добавлена в контекст для параметра позже надо доработать к при работе с приложением. Проблема в том, что правила вычета не допускают такого уточнения. Утверждая, что уточненный тип мог быть добавлен раньше вместо монотипная переменная в лучшем случае является целесообразным.
Ключом к достижению формально удовлетворяющего аргумента является правильное включение контекст внутри уточнения. Формально, типизация совместима с заменой переменных свободного типа.
Таким образом, уточнение свободных переменных означает уточнение всей типизации.
Алгоритм W
[ редактировать ]Алгоритм W |
Отсюда доказательство алгоритма J приводит к алгоритму W, который делает только побочные эффекты, вызванные процедурой явный по выражая его серийный состав посредством замен . Представление алгоритма W на боковой панели по-прежнему использует побочные эффекты. в операциях, выделенных курсивом, но теперь они ограничиваются генерацией свежие символы. Форма судебного решения – это , обозначая функцию с контекстом и выражением в качестве параметра, производящую монотипию вместе с замена. это версия без побочных эффектов из производя замену, которая является наиболее общим объединителем .
Хотя алгоритм W обычно считается алгоритмом HM и часто представленный непосредственно после системы правил в литературе, его цель состоит в том, чтобы описано Милнером [2] на стр. 369 следующим образом:
- В нынешнем виде W вряд ли можно назвать эффективным алгоритмом; замены применяются слишком часто. Он был сформулирован для того, чтобы помочь доказать надежность. Теперь мы представляем более простой алгоритм J, который моделирует W в точном смысле.
Хотя он считал W более сложным и менее эффективным, он представил его в своей публикации перед Дж. Это имеет свои преимущества, когда побочные эффекты недоступны или нежелательны. W также необходим для доказательства полноты, которую он учитывает при доказательстве достоверности.
Обязательства по доказательству
[ редактировать ]Прежде чем сформулировать обязательства по доказательству, необходимо подчеркнуть отклонение между системами правил D и S и представленными алгоритмами.
Несмотря на то, что описанная выше разработка как бы неправильно использовала монотипы в качестве «открытых» переменных доказательства, возможность того, что правильные переменные монотипа могут быть повреждены, была исключена путем введения новых переменных и надежды на лучшее. Но есть одна загвоздка: одно из обещаний заключалось в том, что эти новые переменные будут «иметь в виду» как таковые. Это обещание не выполняется алгоритмом.
Наличие контекста , выражение тоже нельзя вводить или , но алгоритмы придумывают тип , где W дополнительно доставляет замену , это означает, что алгоритм не может обнаружить все ошибки типов. Это упущение можно легко исправить, если более тщательно разграничить доказательства. переменные и переменные-монотипы.
Авторы прекрасно знали о проблеме, но решили не исправлять ее. Можно предположить, что за этим стоит прагматическая причина. Хотя более правильная реализация вывода типа позволила бы алгоритму работать с абстрактными монотипиями, они не были необходимы для предполагаемого применения, где ни один из элементов в ранее существовавшем контексте не имел свободных переменные. В этом свете ненужное усложнение было отброшено в пользу более простого алгоритма. Остающийся недостаток заключается в том, что доказательство алгоритма в отношении системы правил менее общее и может быть выполнено только для контекстов с как побочное условие.
Дополнительное условие в обязательстве полноты указывает на то, что вывод может дать много типов, в то время как алгоритм всегда создает один. В то же время дополнительное условие требует, чтобы выведенный тип был действительно наиболее общим.
Чтобы правильно доказать обязательства, необходимо сначала их усилить, чтобы можно было активировать лемму о замене, пронизывающую замену. через и . Отсюда доказательства проводятся индукцией по выражению.
Еще одним обязательством доказательства является сама лемма о замене, т.е. замена типизации, которая окончательно устанавливает всеквантификацию. Последнее формально невозможно доказать, поскольку такого синтаксиса под рукой нет.
Расширения
[ редактировать ]Рекурсивные определения
[ редактировать ]Чтобы сделать программирование практичным, необходимы рекурсивные функции. Центральное свойство лямбда-исчисления состоит в том, что рекурсивные определения не доступны напрямую, но вместо этого могут быть выражены с помощью комбинатора с фиксированной точкой . Но, к сожалению, комбинатор фиксированных точек невозможно сформулировать в типизированном варианте. лямбда-исчисления, не оказывая катастрофического воздействия на систему, как указано выше. ниже.
Правило ввода
[ редактировать ]Оригинальная бумага [4] показывает, что рекурсия может быть реализована с помощью комбинатора . Таким образом, возможное рекурсивное определение можно сформулировать как .
В качестве альтернативы возможно расширение синтаксиса выражения и дополнительное правило типизации:
где
в основном слияние и включая рекурсивно определенное переменные в позициях монотипии, где они встречаются слева от а как политипы справа от него.
Последствия
[ редактировать ]Несмотря на то, что вышеизложенное очевидно, за это приходится платить.
Теория типов связывает лямбда-исчисление с вычислениями и логикой. Простая модификация, описанная выше, влияет на оба:
- Свойство сильной нормализации становится недействительным, поскольку можно сформулировать незавершающие термины.
- Логика терпит крах, потому что тип становится обитаемым .
Перегрузка
[ редактировать ]Перегрузка означает, что разные функции могут быть определены и использованы с одним и тем же именем. Большинство языков программирования, по крайней мере, обеспечивают перегрузку встроенными арифметическими операциями (+, < и т. д.), чтобы позволить программисту писать арифметические выражения в одной и той же форме, даже для разных числовых типов, таких как int
или real
. Поскольку сочетание этих разных типов в одном и том же выражении также требует неявного преобразования, перегрузка специально для этих операций часто встроена в сам язык программирования. В некоторых языках эта функция обобщена и доступна пользователю, например, в C++.
Хотя специальной перегрузки, поскольку затраты на вычисления как при проверке типов, так и при выводе в функциональном программировании удалось избежать [ нужна ссылка ] было введено средство систематизации перегрузки, которое по форме и названию напоминает объектно-ориентированное программирование, но работает на уровень выше. «Экземпляры» в этой систематике являются не объектами (т.е. на уровне значений), а скорее типами. Пример быстрой сортировки, упомянутый во введении, использует перегрузку в заказах, имеющую следующую аннотацию типа в Haskell:
quickSort :: Ord a => [a] -> [a]
Здесь тип a
не только полиморфен, но и ограничен экземпляром некоторого класса типов. Ord
, который предоставляет предикаты порядка <
и >=
используется в теле функции. Правильные реализации этих предикатов затем передаются в функции быстрой сортировки в качестве дополнительных параметров, как только быстрая сортировка используется для более конкретных типов, обеспечивая единую реализацию перегруженной функции быстрой сортировки.
Поскольку «классы» допускают в качестве аргумента только один тип, результирующая система типов все равно может обеспечить вывод. Кроме того, классы типов могут быть оснащены неким порядком перегрузки, позволяющим расположить классы в виде решетки .
Типы высшего порядка
[ редактировать ]Параметрический полиморфизм подразумевает, что сами типы передаются как параметры, как если бы они были собственными значениями. Передача в качестве аргументов в соответствующие функции, а также в «функции типа», как в константах «параметрического» типа, приводит к вопросу, как более правильно типизировать сами типы. Типы более высокого порядка используются для создания еще более выразительной системы типов.
К сожалению, унификация больше неразрешима при наличии метатипов, что делает невозможным вывод типа в этой степени общности. Кроме того, предположение о том, что тип всех типов включает себя в качестве типа, приводит к парадоксу, как и в случае с множеством всех множеств, поэтому необходимо действовать поэтапно, повышая уровни абстракции. Исследования в области лямбда-исчисления второго порядка , на один шаг вперед, показали, что вывод типа неразрешим в этой общности.
Haskell представляет еще один более высокий уровень под названием kind . В стандартном Haskell виды выводятся и используются не более чем для описания арности конструкторов типов. например, конструктор типа списка рассматривается как сопоставление типа (типа его элементов) с другим типом (типом списка, содержащего указанные элементы); условно это выражается как . Доступны языковые расширения, расширяющие виды для эмуляции функций зависимой системы типов . [9]
Подтипирование
[ редактировать ]Попытки объединить подтипирование и вывод типа вызвали немалое разочарование. Ограничения подтипирования легко накапливать и распространять (в отличие от ограничений равенства типов), делая результирующие ограничения частью выведенных схем типизации. например , где является ограничением переменной типа . Однако, поскольку в этом подходе переменные типов больше не унифицированы, он имеет тенденцию создавать большие и громоздкие схемы типизации, содержащие множество бесполезных переменных типов и ограничений, что затрудняет их чтение и понимание. Поэтому значительные усилия были приложены к упрощению таких схем типизации и их ограничений. использование методов, аналогичных методам недетерминированного конечного автоматного упрощения (NFA) (полезно при наличии выведенных рекурсивных типов). [10] Совсем недавно Долан и Майкрофт [11] формализовал связь между упрощением схемы типизации и упрощением NFA и показал, что алгебраический подход к формализации подтипирования позволяет генерировать компактные основные схемы типизации для ML-подобного языка (называемого MLsub). Примечательно, что предложенная ими схема типизации использовала ограниченную форму типов объединения и пересечения вместо явных ограничений. Позже Парро заявил [12] что эта алгебраическая формулировка эквивалентна относительно простому алгоритму, напоминающему алгоритм W, и что использование типов объединения и пересечения не является обязательным.
С другой стороны, вывод типов оказался более сложным в контексте объектно-ориентированных языков программирования. потому что методы объекта, как правило, требуют первоклассного полиморфизма в стиле Системы F (где вывод типа неразрешим) и из-за таких особенностей, как F-ограниченный полиморфизм . обеспечивающие объектно-ориентированное программирование, такие как Карделли система Следовательно, системы типов с подтипами , , [13] не поддерживают вывод типа в стиле HM.
Полиморфизм строк можно использовать как альтернативу подтипированию для поддержки функций языка, таких как структурные записи. [14] Хотя этот стиль полиморфизма в некоторых отношениях менее гибок, чем подтипирование, в частности, требуется больше полиморфизма, чем это строго необходимо, чтобы справиться с отсутствием направленности в ограничениях типа. его преимущество состоит в том, что его можно довольно легко интегрировать со стандартными алгоритмами HM.
Примечания
[ редактировать ]- ^ Вывод типа Хиндли-Милнера является DEXPTIME -завершенным. Фактически, простое решение о том, является ли программа ML типизированной (без определения типа), само по себе является DEXPTIME -завершенным. Нелинейное поведение действительно проявляется, но в основном из-за патологических воздействий. Таким образом, доказательства теории сложности, полученные Майрсоном (1990) и Кфури, Тюрином и Уржичином (1990), стали неожиданностью для исследовательского сообщества. [ нужна ссылка ]
- ^ В оригинальной статье политипы называются «схемами типов».
- ^ Параметрические типы не присутствовали в оригинальной статье по HM и не нужны для описания метода. Ни одно из приведенных ниже правил вывода не будет их учитывать или даже учитывать. То же самое относится и к непараметрическим «примитивным типам» в указанной статье. Все механизмы вывода полиморфных типов могут быть определены без них. Они включены сюда не только для примера, но и потому, что природа HM полностью связана с параметрическими типами. Это происходит из типа функции , жестко зашитый в правилах вывода ниже, который уже имеет два параметра и представлен здесь только как частный случай.
- ^ Haskell предоставляет расширение языка ScopedTypeVariables, позволяющее включать в область видимости переменные всех количественных типов.
Ссылки
[ редактировать ]- ^ Хиндли, Дж. Роджер (1969). «Основная схема типов объекта в комбинаторной логике». Труды Американского математического общества . 146 : 29–60. дои : 10.2307/1995158 . JSTOR 1995158 .
- ^ Перейти обратно: а б с Милнер, Робин (1978). «Теория полиморфизма типов в программировании». Журнал компьютерных и системных наук . 17 (3): 348–374. CiteSeerX 10.1.1.67.5276 . дои : 10.1016/0022-0000(78)90014-4 . S2CID 388583 .
- ^ Дамас, Луис (1985). Присвоение типов в языках программирования (кандидатская диссертация). Эдинбургский университет. hdl : 1842/13555 . ЦСТ-33-85.
- ^ Перейти обратно: а б с Дамас, Луис; Милнер, Робин (1982). Основные типовые схемы функциональных программ (PDF) . 9-й симпозиум по основам языков программирования (POPL'82). АКМ. стр. 207–212. дои : 10.1145/582153.582176 . ISBN 978-0-89791-065-1 .
- ^ Милнер, Робин (1978), «Теория полиморфизма типов в программировании», Журнал компьютерных и системных наук , 17 (3): 348–375, doi : 10.1016/0022-0000(78)90014-4 , hdl : 20.500 .11820/d16745d7-f113-44f0-a7a3-687c2b709f66
- ^ Уэллс, Дж. Б. (1994). «Типизация и проверка типов в лямбда-исчислении второго порядка эквивалентны и неразрешимы» . Материалы 9-го ежегодного симпозиума IEEE по логике в информатике (LICS) . стр. 176–185. дои : 10.1109/LICS.1994.316068 . ISBN 0-8186-6310-3 . S2CID 15078292 .
- ^ Клемент (1986). Простой аппликативный язык: Mini-ML (PDF) . ЛФП'86. АКМ. дои : 10.1145/319838.319847 . ISBN 978-0-89791-200-6 .
- ^ Воан, Джефф (23 июля 2008 г.) [5 мая 2005 г.]. «Доказательство корректности алгоритма вывода типа Хиндли – Милнера» (PDF) . Архивировано из оригинала (PDF) 24 марта 2012 г.
{{cite journal}}
: Для цитирования журнала требуется|journal=
( помощь ) - ^ Йоргей; Брент; Вейрих; Стефани; Кретин; Жюльен; Пейтон Джонс; Симин; Витиниотис; Дмитрийос; Магальяйнс; Хосе Педро (январь 2012 г.). «Продвижение Haskell» . Материалы TLDI'12 : 53–66. дои : 10.1145/2103786.2103795 . ISBN 978-1-4503-1120-5 .
- ^ Поттье, Франсуа (1998). Вывод типа при наличии подтипирования: от теории к практике (Диссертация) . Проверено 10 августа 2021 г.
- ^ Долан, Стивен; Майкрофт, Алан (2017). «Полиморфизм, подтипирование и вывод типа в MLsub» (PDF) . POPL 2017: Материалы 44-го симпозиума ACM SIGPLAN по принципам языков программирования . дои : 10.1145/3009837.3009882 .
- ^ Парро, Лайонел (2020). «Простая суть алгебраического подтипирования: вывод основного типа с упрощением подтипирования». 25-я Международная конференция ACM SIGPLAN по функциональному программированию — ICFP 2020, [Онлайн-мероприятие], 24–26 августа 2020 г. дои : 10.1145/3409006 .
- ^ Карделли, Лука; Мартини, Симона; Митчелл, Джон К.; Щедров, Андре (1994). «Расширение системы F с подтипированием». Информация и вычисления, том. 9 . Северная Голландия, Амстердам. стр. 4–56. дои : 10.1006/inco.1994.1013 .
- ^ Даан Лейен, Расширяемые записи с метками с ограниченной областью действия , Институт информационных и вычислительных наук, Утрехтский университет, проект, редакция: 76, 23 июля 2005 г.
- Майрсон, Гарри Г. (1990). «Решение о типизации ML завершено для детерминированного экспоненциального времени». Материалы 17-го симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования - POPL '90 . АКМ. стр. 382–401. дои : 10.1145/96709.96748 . ISBN 978-0-89791-343-0 . S2CID 75336 .
- Кфури, Эй Джей; Тюрин Дж.; Уржичин, П. (1990). «Типируемость ML завершена с учетом времени dexptime». Каап '90 . Конспекты лекций по информатике. Том. 431. С. 206–220. дои : 10.1007/3-540-52590-4_50 . ISBN 978-3-540-52590-5 .