"Какую часть Хиндли-Милнера вы не понимаете?"

Клянусь, когда-то была футболка для продажи с бессмертными словами:


Какая часть

Hindley-Milner

ты не понимаешь?


В моем случае ответ будет... все это!

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

Я понимаю буквы греческого алфавита, конечно, и символы, такие как "∉" (что обычно означает, что что-то не является элементом набора).

С другой стороны, я никогда раньше не видел "⊢" (Wikipedia утверждает, что это может означать "раздел"). Я также не знаком с использованием винкулума здесь. (Обычно это обозначает дробь, но, похоже, это не так).

Если бы кто-нибудь мог хотя бы сказать мне, где начать понимать, что означает это море символов, это было бы полезно.

752
21 сент. '12 в 17:29
источник поделиться
7 ответов
  • Горизонтальная полоска означает, что "[выше] подразумевает [ниже]".
  • Если в [выше] есть несколько выражений, рассмотрите их anded; все [выше] должны быть истинными, чтобы гарантировать [ниже].
  • : означает имеет тип
  • означает находится в. (Аналогично означает, что "нет".)
  • Γ обычно используется для обозначения среды или контекста; в этом случае его можно рассматривать как набор аннотаций типа, сопрягая идентификатор с его типом. Поэтому x : σ ∈ Γ означает, что среда Γ включает в себя тот факт, что x имеет тип σ.
  • можно прочитать как доказать или определяет. Γ ⊢ x : σ означает, что среда Γ определяет, что x имеет тип σ.
  • , является способом , включая конкретные дополнительные предположения в среду Γ.
    Следовательно, Γ, x : τ ⊢ e : τ' означает, что среда Γ, с дополнительным, переопределяющим предположением о том, что x имеет тип τ, доказывает, что e имеет тип τ'.
566
21 сент. '12 в 20:28
источник

Связанные вопросы


Похожие вопросы

Этот синтаксис, хотя он может выглядеть сложным, на самом деле довольно прост. Основная идея исходит из логики: все выражение является импликацией, а верхняя половина - предположениями, а нижняя половина - результатом. То есть, если вы знаете, что верхние выражения верны, вы можете сделать вывод, что нижние выражения также истинны.

Символы

Еще одна вещь, о которой следует помнить, состоит в том, что некоторые буквы имеют традиционные значения; в частности, Γ представляет собой "контекст", в котором вы находитесь, то есть какие типы других вещей вы видели. Итак, что-то вроде Γ ⊢ ... означает "выражение ..., когда вы знаете типы каждого выражения в Γ.

Символ по существу означает, что вы можете что-то доказать. Итак, Γ ⊢ ... - это утверждение, в котором говорится: "Я могу доказать ... в контексте Γ. Эти утверждения также называются суждениями типа.

Еще одна вещь, о которой нужно помнить: в математике, как ML и Scala, x : σ означает, что x имеет тип σ. Вы можете прочитать его так же, как Haskell x :: σ.

Что означает каждое правило

Итак, зная это, первое выражение становится понятным: если мы знаем, что x : σ ∈ Γ (т.е. x имеет некоторый тип σ в некотором контексте Γ), то мы знаем, что Γ ⊢ x : σ (т.е. в Γ, x имеет тип σ). Так что, действительно, это не говорит вам ничего супер интересного; он просто говорит вам, как использовать свой контекст.

Другие правила также просты. Например, возьмите [App]. Это правило имеет два условия: e₀ - это функция от некоторого типа τ к некоторому типу τ', а e₁ - значение типа τ. Теперь вы знаете, какой тип вы получите, применив e₀ к e₁! Надеюсь, это не удивительно:).

В следующем правиле есть еще несколько новых синтаксисов. В частности, Γ, x : τ означает только контекст, состоящий из Γ и суждения x : τ. Итак, если мы знаем, что переменная x имеет тип τ, а выражение e имеет тип τ', мы также знаем тип функции, которая принимает x и возвращает e. Это просто говорит нам, что делать, если мы выяснили, какой тип выполняет функция и какой тип она возвращает, поэтому также не удивительно.

Следующий расскажет вам, как обращаться с операторами let. Если вы знаете, что какое-то выражение e₁ имеет тип τ, если x имеет тип σ, тогда выражение let, которое локально связывает x со значением типа σ, будет e₁ имеют тип τ. Действительно, это просто говорит вам, что оператор let существенно расширяет контекст с помощью новой привязки, что и делает let!

Правило [Inst] имеет дело с подтипированием. Он говорит, что если у вас есть значение типа σ' и это подтип σ ( представляет отношение частичного упорядочения), то это выражение также имеет тип σ.

В последнем правиле рассматриваются обобщающие типы. Быстрая сторона: свободная переменная - это переменная, которая не вводится let-statement или lambda внутри некоторого выражения; это выражение теперь зависит от значения свободной переменной от ее контекста. Правило говорит, что если есть какая-то переменная α, которая не является "свободной" ни в чем в вашем контексте, то можно с уверенностью сказать, что любое выражение, тип, который вы знаете, e : σ будет иметь этот тип для любого значения α.

Как использовать правила

Итак, теперь, когда вы понимаете символы, что вы делаете с этими правилами? Ну, вы можете использовать эти правила, чтобы определить тип различных значений. Чтобы сделать это, посмотрите на свое выражение (скажем f x y) и найдите правило, в котором есть вывод (нижняя часть), который соответствует вашему утверждению. Позвольте назвать вещь, которую вы пытаетесь найти в своей "цели". В этом случае вы должны посмотреть правило, заканчивающееся на e₀ e₁. Когда вы это нашли, вам нужно найти правила, доказывающие все выше строки этого правила. Эти вещи в целом соответствуют типам подвыражений, поэтому вы, по сути, рекурсируете по частям выражения. Вы просто делаете это, пока не закончите свое дерево доказательств, которое даст вам доказательство типа вашего выражения.

Итак, все эти правила задают точно - и в обычной математически педантичной детали: P-как определить типы выражений.

Теперь это должно звучать знакомо, если вы когда-либо использовали Prolog - вы, по сути, вычисляете дерево доказательств, как человеческий интерпретатор Prolog. Существует причина, по которой Prolog называется "логическое программирование"! Это также важно, так как первый способ, которым я был введен в алгоритм вывода H-M, был реализован в Prolog. Это на самом деле удивительно просто и делает все ясно. Вы обязательно должны попробовать.

Примечание. Вероятно, я допустил некоторые ошибки в этом объяснении, и мне понравилось бы, если кто-нибудь укажет их. Я действительно буду освещать это в классе через пару недель, поэтому я буду более уверен в этом: P.

302
21 сент. '12 в 19:49
источник

Если бы кто-нибудь мог хотя бы сказать мне, где начать понимать, что означает это море символов.

См. " Практические основы языков программирования.", главы 2 и 3, о стиле логики через суждениями и выводами. Вся книга теперь доступна на Amazon.

Глава 2

Индуктивные определения

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

2.1 Суждения

Начнем с понятия суждения или утверждения о синтаксическом объекте. Мы будем использовать множество форм суждения, включая такие примеры, как:

  • n nat - n - натуральное число
  • n = n1 + n2 - n - сумма n1 и n2
  • τ тип - τ - тип
  • e: τ - выражение e имеет тип τ
  • e ⇓ v - выражение e имеет значение v

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

69
21 сент. '12 в 18:24
источник

Обозначение происходит из естественной дедукции.

⊢ символ называется turnstile.

6 правил очень просты.

Правило

Var - довольно тривиальное правило - оно говорит, что если тип для идентификатора уже присутствует в вашей среде типа, то выведите тип, который вы просто берете из среды, как есть.

Правило

App гласит, что если у вас есть два идентификатора e0 и e1 и вы можете вывести их типы, вы можете сделать вывод о типе приложения e0 e1. Правило читается так, если вы знаете, что e0 :: t0 -> t1 и e1 :: t0 (то же t0!), То приложение хорошо напечатано и тип t1.

Abs и Let - правила для вывода типов для лямбда-абстракции и впуска.

Inst правило говорит, что вы можете заменить тип менее общим.

45
21 сент. '12 в 19:21
источник

Я полагаю, что SO не является хорошим местом для объяснения всего алгоритма Милнера Хиндли.

Если вы ищете хорошее объяснение алгоритма, лучшее, что я нашел до сих пор, находится в главе 30 Шрирама Кришнамурти Языки программирования: приложение и интерпретация (лицензия CC!). Вот одна веская причина, почему это хорошее объяснение: примеры!

Sample page: "30.1.1  Example: Factorial"

39
25 апр. '13 в 16:11
источник

Как я понимаю правила Хиндли-Милнера?

Хиндли-Милнер - это набор правил в виде секвенциального исчисления (не естественный вывод), в котором говорится, что вы можете вывести (наиболее общий) тип программы из построения программы без явных деклараций типа.

Символы и обозначения

Во-первых, позвольте объяснить символы

  • 𝑥 является идентификатором (неформально, имя переменной).
  • : означает тип (неформально, экземпляр или "is-a").
  • σ (сигма) - выражение, которое является либо переменной, либо функцией.
  • ∈ означает элемент
  • Γ (Гамма) является средой.
  • (знак утверждения) означает, что утверждает (или доказывает, но контекстуально "утверждает" читает лучше.)
  • Γ⊦ 𝑥 : σ, таким образом, читается Γ утверждает 𝑥, a σ
  • 𝑒 является фактическим экземпляром (элементом) типа σ.
  • τ (tau) - тип: базовый, переменный (α), функциональный τ → τ ' или произведение τ × τ'
  • τ → τ ' является функциональным типом, где τ и τ' - типы.
  • λ𝑥.𝑒 означает λ (lambda) - анонимная функция, которая принимает аргумент 𝑥 и возвращает выражение 𝑒.
  • пусть 𝑥 = 𝑒₀ в 𝑒₁ означает в выражении 𝑒₁, замените 𝑒₀ везде, где появляется 𝑥.
  • означает, что предшествующий элемент является подтипом (неформально - подкласс) последнего элемента.
  • α - переменная типа.
  • α.σ - это тип, переменные аргумента ∀ (для всех), α, возвращающее выражение σ
  • free (Γ) означает не элемент переменных свободного типа из Γ, определенных во внешнем контексте. (Связанные переменные являются взаимозаменяемыми.)

Все выше линии - это предпосылка, все ниже - вывод (Пер Мартин-Лёф)

Далее следует английская интерпретация логических утверждений, за которой следует объяснение.

переменная

VAR Logic Diagram

Учитывая, что 𝑥 является типом σ (сигма), элемент Γ (Gamma),
заключение Γ утверждает, что 𝑥 является σ.

Это в основном тавтология - имя идентификатора - это переменная или функция.

Функциональное приложение

APP Logic Diagram

Учитывая, что Γ утверждает, 𝑒₀ является функциональным типом, а Γ утверждает, что 𝑒₁ является τ
заключение Γ утверждает, что применение функции 𝑒₀ к 𝑒₁ является типом τ '

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

Функция Абстракция

ABS Logic Diagram

Учитывая, что Γ и 𝑥 типа τ утверждает, что 𝑒 является типом, τ '
заключение Γ утверждает анонимную функцию, λ 𝑥 возвращающего выражения, 𝑒 имеет тип τ → τ '.

Это означает, что если мы знаем, что 𝑥 имеет тип τ и, следовательно, выражение 𝑒 имеет тип τ ', то функция 𝑥 возвращающего выражения 𝑒 имеет тип τ → τ'.

Пусть объявление переменной

LET Logic Diagram

Учитывая, что Γ утверждает 𝑒₀, типа σ, а Γ и 𝑥 типа σ, утверждает 𝑒₁ типа τ
заключить Γ утверждает, let 𝑥 = 𝑒₀ in 𝑒₁ типа т

Это означает, что если мы имеем выражение 𝑒₀, которое является σ (являющимся переменной или функцией), а некоторое имя 𝑥 также является σ и выражением 𝑒₁ типа τ, то мы можем заменить 𝑒₀ на 𝑥, где бы он ни находился внутри of 𝑒₁.

Конкретизация

INST Logic Diagram

Учитывая, что Γ утверждает 𝑒 типа σ ', а σ' является подтипом σ
заключение Γ утверждает, что 𝑒 имеет тип σ

Это говорит о том, что если экземпляр имеет тип, являющийся подтипом другого типа, он также является экземпляром этого супертипа.

Это позволяет нам использовать экземпляр типа в более общем смысле, чтобы выражение могло возвращать более конкретный тип.

Обобщение

GEN Logic Diagram

Учитывая, что Γ утверждает, что 𝑒 является σ и α не является элементом свободных переменных Γ,
заключение Γ утверждает 𝑒, тип для всех выражений аргументов α, возвращающих σ-выражение

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

Заключение

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

27
04 февр. '17 в 2:01
источник

Есть два способа думать о e: σ. Один из них: "выражение e имеет тип σ", другое - "упорядоченная пара выражения e и тип σ".

Просмотр Γ как знания о типах выражений, реализованных как набор пар выражения и типа, e: σ.

Турникет ⊢ означает, что из знания слева, мы можем вывести, что справа.

Таким образом, первое правило [Var] можно прочитать:
Если наше знание Γ содержит пару e: σ, то из Γ можно вывести, что e имеет тип σ.

Второе правило [App] можно прочитать:
Если из Γ можно вывести, что e_0 имеет тип τ → τ ', а из Γ можно вывести, что e_1 имеет тип τ, то из Γ можно вывести, что e_0 e_1 имеет тип τ'.

Общепринято писать Γ, e: σ вместо Γ ∪ {e: σ}.

Таким образом, можно прочитать третье правило [Abs]:
Если мы из Γ, расширенной с x: τ, можем вывести, что e имеет тип τ ', то из Γ можно вывести, что λx.e имеет тип τ → τ'.

Четвертое правило [Let] остается упражнением.: -)

Пятое правило [Inst] можно прочитать:
Если мы из Г можем вывести, что e имеет тип σ ', а σ' - подтип σ, то из Γ можно вывести, что e имеет тип σ.

Шестое и последнее правило [Gen] можно прочитать:
Если мы из Γ можем вывести, что e имеет тип σ, а α не является переменной свободного типа в любом из типов в Γ, то из Γ можно вывести, что e имеет тип ∀α σ.

16
25 апр. '13 в 17:55
источник

Посмотрите другие вопросы по меткам или Задайте вопрос