Я працюю над компілятором для конкатенативної мови і хотів би додати підтримку виводу типу. Я розумію Хіндлі – Мілнера, але я вивчав теорію типів, коли йду, тому не знаю, як її адаптувати. Чи є наступна система звуковою і, можливо, незмінною?
Термін - це буквальне слово, склад термінів, цитата терміна або примітив.
Усі терміни позначають функції. Для двох функцій і e 2 , e 1 , тобто протиставлення позначає зворотний склад. Літерали позначаютьladin функції.
Терміни, окрім складу, мають основні правила типу:
Особливо відсутні правила застосування, оскільки в мовах сполучення їх немає.
Тип - це буквальний, змінний тип, або функція від стеків до стеків, де стек визначається як правильний вкладений кортеж. Усі функції неявно поліморфні щодо «решти стека».
Це перше, що здається підозрілим, але я не знаю точно, що з цим.
Щоб допомогти читаності і скоротити дужки, я буду вважати , що у типних схемах. Я також буду використовувати велику літеру для змінної, що позначає стек, а не одиничне значення.
Є шість примітивів. Перші п’ять досить нешкідливі. dup
приймає найвище значення і виробляє дві його копії. swap
змінює порядок двох перших значень. pop
відкидає найвище значення. quote
приймає значення і виробляє пропозицію (функцію), яка повертає його. apply
застосовує котирування до стеку.
Останній комбінатор compose
повинен взяти дві цитати та повернути тип їх конкатенації, тобто . У статично типізованій конкатенативній мовіCatтипдуже прямолінійний.compose
Однак цей тип є занадто обмежуючим: він вимагає, щоб виробляти першу функцію точно відповідало споживанню другої. Насправді ви повинні взяти на себе різні типи, а потім уніфікувати їх. Але як би ти написав цей тип?
Якщо дозволити позначати різницю двох типів, то я думаю, ви можете compose
правильно написати тип .
Це по - , як і раніше відносно проста: compose
приймає функцію і один F 2 : D → E . Його результат споживає B зверху споживання f 2, не вироблене f 1 , і виробляє D на вершині виробництва f 1, не споживаного f 2 . Це дає правило для звичайної композиції.
Однак я не знаю, що ця гіпотетична насправді відповідає чому-небудь, і я досить довго переслідував її по колах, я вважаю, що я прийняв неправильний поворот. Чи може це бути простою різницею кортежів?
Чи є в цьому щось жахливо зламане, чого я не бачу, чи я на чомусь схожий на правильний шлях? (Я, мабуть, неправильно оцінив деякі з цих матеріалів і вдячний за виправлення в цій області.)
compose
занадто обмежувальне? У мене таке враження, що це добре. (наприклад, обмеження можна було б обробити об'єднанням, як для застосування, як у λ-обчисленні)
twice
як визначений як dup compose apply
, який бере пропозицію і застосовує її двічі. [1 +] twice
добре: ви складаєте дві функції типу . Але це не так: якщо ∀ A[pop] twice
, проблема полягає в тому, що A ≠ , тому вираз заборонено, навіть якщо він повинен бути дійсним і мати тип ∀ A b .compose