Введіть умовивід з типами продуктів


15

Я працюю над компілятором для конкатенативної мови і хотів би додати підтримку виводу типу. Я розумію Хіндлі – Мілнера, але я вивчав теорію типів, коли йду, тому не знаю, як її адаптувати. Чи є наступна система звуковою і, можливо, незмінною?

Термін - це буквальне слово, склад термінів, цитата терміна або примітив.

e::=x|ee|[e]|

Усі терміни позначають функції. Для двох функцій і e 2 , e 1e1e2 , тобто протиставлення позначає зворотний склад. Літерали позначаютьladin функції.e1e2=e2e1

Терміни, окрім складу, мають основні правила типу:

x:ι[Lit]Γe:σΓ[e]:α.ασ×α[Quot],α not free in Γ

Особливо відсутні правила застосування, оскільки в мовах сполучення їх немає.

Тип - це буквальний, змінний тип, або функція від стеків до стеків, де стек визначається як правильний вкладений кортеж. Усі функції неявно поліморфні щодо «решти стека».

τ::=ι|α|ρρρ::=()|τ×ρσ::=τ|α.σ

Це перше, що здається підозрілим, але я не знаю точно, що з цим.

Щоб допомогти читаності і скоротити дужки, я буду вважати , що у типних схемах. Я також буду використовувати велику літеру для змінної, що позначає стек, а не одиничне значення.ab=b×(a)

Є шість примітивів. Перші п’ять досить нешкідливі. dupприймає найвище значення і виробляє дві його копії. swapзмінює порядок двох перших значень. popвідкидає найвище значення. quoteприймає значення і виробляє пропозицію (функцію), яка повертає його. applyзастосовує котирування до стеку.

dup::Ab.AbAbbswap::Abc.AbcAcbpop::Ab.AbAquote::Ab.AbA(C.CCb)apply::AB.A(AB)B

Останній комбінатор composeповинен взяти дві цитати та повернути тип їх конкатенації, тобто . У статично типізованій конкатенативній мовіCatтипдуже прямолінійний.[e1][e2]compose=[e1e2]compose

compose::ABCD.A(BC)(CD)A(BD)

Однак цей тип є занадто обмежуючим: він вимагає, щоб виробляти першу функцію точно відповідало споживанню другої. Насправді ви повинні взяти на себе різні типи, а потім уніфікувати їх. Але як би ти написав цей тип?

compose::ABCDE.A(BC)(DE)A

Якщо дозволити позначати різницю двох типів, то я думаю, ви можете composeправильно написати тип .

compose::ABCDE.A(BC)(DE)A((DC)B((CD)E))

Це по - , як і раніше відносно проста: composeприймає функцію і один F 2 : D E . Його результат споживає B зверху споживання f 2, не вироблене f 1 , і виробляє D на вершині виробництва f 1, не споживаного f 2 . Це дає правило для звичайної композиції.f1:BCf2:DEBf2f1Df1f2

Γe1:AB.ABΓe2:CD.CDΓe1e2:((CB)A((BC)D))[Comp]

Однак я не знаю, що ця гіпотетична насправді відповідає чому-небудь, і я досить довго переслідував її по колах, я вважаю, що я прийняв неправильний поворот. Чи може це бути простою різницею кортежів?

A.()A=()A.A()=AABCD.ABCD=BD iff A=Cotherwise=undefined

Чи є в цьому щось жахливо зламане, чого я не бачу, чи я на чомусь схожий на правильний шлях? (Я, мабуть, неправильно оцінив деякі з цих матеріалів і вдячний за виправлення в цій області.)


Як ви використовуєте змінні у своїй граматиці? Це запитання має допомогти вам в обробці "підтипу", який вам здається потрібним.
jmad

1
@jmad: Я не впевнений, що розумію питання. Змінні типу існують саме для того, щоб формально визначити схеми типів, а сама мова взагалі не має змінних, а лише визначення, які можуть бути [взаємно] рекурсивними.
Джон Перді

Справедливо. Чи можете ви сказати, чому (можливо, на прикладі) правило composeзанадто обмежувальне? У мене таке враження, що це добре. (наприклад, обмеження можна було б обробити об'єднанням, як для застосування, як у λ-обчисленні)С=D
jmad

@jmad: Звичайно. Розглянемо twiceяк визначений як dup compose apply, який бере пропозицію і застосовує її двічі. [1 +] twiceдобре: ви складаєте дві функції типу . Але це не так: якщо Aιι[pop] twice , проблема полягає в тому, що A Аб.f1,f2:АбА , тому вираз заборонено, навіть якщо він повинен бути дійсним і мати типA b .ААбАб.АббАcompose

Відповіді:


9

складати:АБСδ.δ (α.α АαБ) (β.β БβС)δ (γ.γ АγС)
видається достатньо загальним. Це набагато поліморфніше, ніж тип, запропонований у питанні. Тут змінна кількісно визначається за суміжними фрагментами стека, що фіксує функції багатьох аргументів.

Грецькі літери використовуються для змінних решти стека лише для наочності.

Він виражає обмеження, що вихідний стек першого елемента на стеку повинен бути таким же, як і вхідний стек другого елемента. Відповідне інстанціювання змінноїБ для двох власне аргументів - це спосіб отримання обмежень для належної роботи, а не визначення нової операції, як ви пропонуєте у питанні.

Я вважаю, що перевірка типів типів 2 загалом не визначається, хоча зроблено певну роботу, яка дає хороші результати на практиці (для Haskell):

  • Саймон Л. Пейтон Джонс, Дімітріос Вітініотис, Стефані Вейріх, Марк Шилдс: Практичне виведення типу для довільно-рангових типів. J. Функція. Програма. 17 (1): 1-82 (2007)

Правило типу композиції просто:

Γе1:α.α Аα БΓе1:α.α Бα СΓе1 е2:α.α Аα С

Щоб система типів працювала в цілому, вам потрібно таке правило спеціалізації:

Γe:α.α Aα BΓe:α.C Aα C B

Thanks, this was very helpful. This type is correct for functions of a single argument, but it doesn’t support multiple arguments. For instance, dup + should have type ιι because + has type ιιι. But type inference in the absence of annotations is an absolute requirement, so clearly I need to go back to the drawing board. I have an idea for another approach to pursue, though, and will blog about it if it works out.
Jon Purdy

1
The stack types quantify over stack fragments, so there is no problem dealing with two argument functions. I'm not sure how this applies to dup +, as that does not use compose, as you defined it above.
Dave Clarke

Er, right, I meant [dup] [+] compose. But I read αB as B×α; say B=ι×ι; then you have (ι×ι)×α and not ι×(ι×α). Гніздування неправильно, якщо ви не переверніть стек навколо, щоб верхній був останнім (найглибшим вкладеним) елементом.
Джон Перді

Я, можливо, будую свій стек у неправильному напрямку. Я не думаю, що вкладення має значення, доки пари, що складають стек, не з'являються на мові програмування. (Я планую оновити свою відповідь, але спочатку потрібно зробити невелике дослідження.)
Дейв Кларк

Так, вкладення - це майже деталь реалізації.
Джон Перді
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.