Чи є універсальні типи екзистенціальними типами, або окремим випадком?


20

Мені хотілося б знати, чи універсально кількісний тип : є підтипом, або окремий випадок екзистенційно кількісно визначеного типу з однаковим підписом:Ta

Ta=X:{aX,f:X{T,F}}
Te
Te=X:{aX,f:X{T,F}}

Я б сказав "так": Якщо щось відповідає дійсності "для всіх X" ( ), то воно також повинно бути правдою "для деякого X" ( \ існує X ). Тобто, оператор з " \ forall " є просто більш обмеженою версією того самого виразу з " \ існує ": ∀X, P (X) \ overset? \ Означає ∃X, P (X).XX

X,P(X)?X,P(X).

Я десь помиляюся?

Передумови: Чому я це запитую?

Я вивчаю екзистенційні типи, щоб зрозуміти, чому і як "Анотаційні [дані] типи мають екзистенціальний тип" . Я не можу зрозуміти це поняття лише з теорії; Мені потрібні і конкретні приклади.

На жаль, хороших прикладів коду важко знайти, оскільки більшість мов програмування мають лише обмежену підтримку екзистенційних типів. (Наприклад, підстановочні символи Haskellforall або Java? .) З іншого боку, універсально кількісні типи підтримуються багатьма останніми мовами через "generics".

Що ще гірше, схоже , що дженерики легко легко змішуються з екзистенціальними типами , що ще важче розмежовує екзистенціальність від універсальних типів. Мені цікаво, чому таке змішування відбувається так легко. Відповідь на це питання може пояснити це: Якщо універсальні типи справді є лише окремим випадком екзистенціальних типів, то не дивно, що загальні типи, наприклад, Java List<T>, можна трактувати будь-яким способом.


1
У чому навіть різниця між універсальним та екзистенціальним?

Математично кажучи, ви маєте рацію: якщо forall x. P(x)тоді exists x. P(x). Чи враховують системи типів це під час перевірки типів ... Я поняття не маю. +1 для цікавого питання.

1
@deinan: Якщо P (x) не відповідає жодному x , то, звичайно, ∀xP (x) не дотримується. Те, що ви, мабуть, мали на увазі, коли немає x , тобто ∀x∈XP (x) не означає ∃x∈XP (x), якщо X = ∅ .

1
... І зауважте, що якщо вони переписані без заданих позначень, вони виглядатимуть інакше: ∀xx∈X⇒P (x) проти ∃xx∈X & P (x) і що ∃xx∈X⇒P (x) буде тривіально задоволено ні й не з X .

1
Класне питання. У Haskell, безумовно, вірно, що значення типу (forall b. Show b => b) може бути передано функції, яка приймає (forall b. B), але не навпаки, маючи на увазі замінність, яку ви очікуєте від підтипові відносини. Але звичайно, коли ви говорите про типи, вам слід згадати про типову систему, на яку ви дивитесь, особливо, якщо ви маєте на увазі формальну алгебру типу для своєї семантики ...

Відповіді:


10

По-перше, з математичної точки зору не означає x : T , P ( x ) . Імплементація має місце тоді і лише тоді, коли T не порожній. Однак у мовах програмування нечасто мати справу з порожніми типами (хоча це буває).x:T,P(x)x:T,P(x)T

З математичної точки зору, навіть коли , два не є однаковими. Якщо ви даєте типам набір семантики, то T a - це супернабір T e , не той самий тип. (Насправді це не суперсет; він близький до ізоморфного до суперсети.)(x:T,P(x))(x:T,P(x))TaTe

Давайте ближче до теорії мови програмування та подивимось, що ці типи означають насправді. представляє собою універсальний тип: якщо ви маєте значення А цього типу, можна побудувати A ( M ) для будь-якого M : X . Зокрема, якщо у вас є M 1 і M 2 типу X , ви можете побудувати A ( MTa=X.{a:X,f:Xbool}AA(M)M:XM1M2X і A ( M 2 ) . По суті (і, можливо, фактично, залежно від мови) T a - це функція від типів до термінів. Як такий, універсальний тип забезпечуєпараметризаціютипу: одне значення працює для всіх типів. Універсальні типи лежать в основіполіморфізму.A(M1)A(M2)Ta

Екзистенціальний типу - зовсім інший звір. Враховуючи значення B типу T e , існує лише один додаток N : X такий, що π 1 ( B ) = N , і для цього терміна π 2 ( B ) = { a : N , f :Te=X.{a:X,f:Xbool}BTeN:Xπ1(B)=N . Екзистенціальний тип забезпечує спосіб приховати природу N ; це говорить: "Існує тип! Але я не скажу тобі яке! ”. Як такий, екзистенційний тип забезпечуєабстрагуваннятипу: одне конкретне приховане значення. Екзистенційні типи лежать в основімодульних систем.π2(B)={a:N,f:Nbool}N

Не вводьте в оману Хаскелла forall: незважаючи на його назву, це форма екзистенціального кількісного показника.

Для переконливості я настійно рекомендую типи та мови програмування (глави 23 та 24 обговорюють відповідно універсальні типи та екзистенційні типи). Це дасть корисну основу для розуміння статей дослідження.


1
Один незначний, і досить пізній, каламбур - Хаскелла forallсправді є універсальним кількісним показником у первісному контексті неявного кількісного визначення, яке він робить явним, а саме перегляду поліморфних типів "ззовні" для визначення вищого рівня. «Внутрішнє» такого визначення при маніпулюванні аргументами поліморфні типи є фактично екзистенційними; кожна змінна типу пов'язана з певним типом, але ми не знаємо (і не можемо), що це за тип. Наскільки мені відомо, жодна реалізація Haskell не підтримує істинних (сирих, найвищого рівня) екзистенціальних типів, і мені незрозуміло, якій цілі це навіть би слугувало.
CA McCann

1
Екзистенціальні типи, підтримувані GHC, - це типи, які (прямо чи опосередковано) мають універсальні квантори, які, видно ззовні ", зустрічаються у противаріантному положенні. Це використовує приблизно таку саму подвійність, як і логічне заперечення, тому для того, щоб мати такі екзистенціальні типи на верхньому рівні, вони повинні бути вдвічі протилежними, використовуючи кодування, схоже на CPS (це еквівалентність, яку дає Удай Редді). Зауважимо, що екзистенційні кількісні показники в інтуїтивістичному вигляді представляють подібні незручності з аналогічних причин.
CA McCann

5

Ваша інтуїція , що має бути вкладається вX .X.P(X) взагалі вірно. Він не працює, якщо вся колекція типів порожня, що трапляється рідко.X.P(X)

Однак на прикладі конкретних ви дали не є хорошим. Значення цього типу повинно бути здатне створювати елемент кожного типу X (для першого компонента пари). Якщо ви думаєте про типи як набори, така річ неможлива. Отже, цей тип порожній. Він буде включений в кожному типі, зокрема екзистенціального типуX .X.(X×(XBool))XX.(X×(XBool))

 f (p: \forall X. (X * (X -> Bool))) = PACK X = Bool WITH p[Bool]

Стаття, яку ви згадуєте про екзистенційні типи, є трохи теоретичною. Більш детальна стаття - праця Карделлі та Вегнера: Про розуміння типів, абстрагування даних та поліморфізм . Більшість сучасних підручників з мов програмування також мали б обговорення екзистенційних типів. Гарною книжкою, яку слід шукати, були б основи Мітчелла мов програмування .

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

X.P(X)Y.(X.P(X)Y)Y

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