Czy typy uniwersalne są podtypem, czy specjalnym przypadkiem typów egzystencjalnych?


20

Chciałbym wiedzieć, czy uniwersalnie skwantyfikowany typ : T a = X : { a X , f : X { T , F } } jest podtypem lub przypadkiem szczególnym skwantyfikowanego egzystencjalnie wpisz T e z tym samym podpisem: T e = X : { a X , f : X { T , F } }Ta

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

Powiedziałbym „tak”: Jeśli coś jest prawdą „dla wszystkich X” ( ), to musi być również prawdziwe „dla niektórych X” ( X ). Oznacza to, że instrukcja z „ ” jest po prostu bardziej ograniczoną wersją tej samej instrukcji z „ ”: X , P ( X ) ?XX

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

Czy gdzieś się mylę?

Tło: Dlaczego o to pytam?

Studiuję typy egzystencjalne, aby zrozumieć, dlaczego i jak „typy abstrakcyjne [dane] mają typ egzystencjalny” . Nie mogę dobrze zrozumieć tej koncepcji na podstawie samej teorii; Potrzebuję też konkretnych przykładów.

Niestety trudno znaleźć dobre przykłady kodu, ponieważ większość języków programowania ma ograniczoną obsługę typów egzystencjalnych. (Na przykład symbole wieloznaczne Haskellaforall lub Javy? .) Z drugiej strony typy uniwersalne są obsługiwane przez wiele najnowszych języków za pomocą „ogólnych”.

Co gorsza, generyczne wydają się łatwo mieszać z typami egzystencjalnymi , co jeszcze bardziej utrudnia odróżnienie typów egzystencjalnych od uniwersalnych. Jestem ciekawy, dlaczego takie pomieszanie występuje tak łatwo. Odpowiedź na to pytanie może to wyjaśnić: jeśli typy uniwersalne są rzeczywiście tylko szczególnym przypadkiem typów egzystencjalnych, nic dziwnego, że typy ogólne, np. Java List<T>, mogą być interpretowane w obie strony.


1
Jaka jest nawet różnica między uniwersalnym a egzystencjalnym?

Z matematycznego punktu widzenia masz rację: jeśli forall x. P(x)tak exists x. P(x). Czy systemy typów uwzględniają to przy sprawdzaniu typów ... Nie mam pojęcia. +1 za interesujące pytanie.

1
@deinan: Jeśli P (x) nie ma żadnego x , to na pewno ∀xP (x) nie ma. Prawdopodobnie miałeś na myśli to, że gdy nie ma x , to znaczy ∀x∈XP (x) nie oznacza ∃x∈XP (x), jeśli X = ∅ .

1
... I zauważ, że jeśli zostaną przepisane bez ustawionej notacji, będą wyglądać inaczej: ∀xx∈X⇒P (x) vs. ∃xx∈X & P (x) i że ∃xx∈X⇒P (x) zostanie spełniony trywialnie żadnymi x nie z X .

1
Fajne pytanie. W Haskell z pewnością prawdą jest, że wartość typu (forall b. Show b => b) może zostać przekazana do funkcji, która przyjmuje (forall b. B), ale nie odwrotnie, co oznacza, że ​​można oczekiwać podstawienia związek podtytułu. Ale oczywiście, kiedy mówisz o typach, powinieneś wspomnieć o systemie typów, na który patrzysz, szczególnie jeśli masz na myśli algebrę formalną dla swojej semantyki ...

Odpowiedzi:


10

x:T,P(x)x:T,P(x)T

(x:T,P(x))(x:T,P(x))TaTe

Ta=X.{a:X,f:Xbool}AA(M)M:XM1M2XA(M1)A(M2)Ta

Te=X.{a:X,f:Xbool}BTeN:Xπ1(B)=Nπ2(B)={a:N,f:Nbool}N

Nie daj się zwieść Haskellowi forall: pomimo nazwy jest to forma egzystencjalnego kwantyfikatora.

W tle zdecydowanie polecam Typy i Języki programowania (rozdziały 23 i 24 omawiają odpowiednio typy uniwersalne i typy egzystencjalne). Zapewni przydatne tło do zrozumienia artykułów badawczych.


1
Jeden drobny i dość późny spór - Haskell foralljest rzeczywiście uniwersalnym kwantyfikatorem w oryginalnym kontekście ukrytej kwantyfikacji, którą wyraźnie określa, mianowicie oglądając typy polimorficzne „z zewnątrz” dla definicji najwyższego poziomu. W „wnętrzu” takiej definicji, manipulując argumentami, typy polimorficzne są faktycznie egzystencjalne; każda zmienna typu jest powiązana z jakimś typem, ale nie wiemy (i nie możemy), czym jest ten typ. Według mojej wiedzy żadna implementacja Haskell nie obsługuje prawdziwych (surowych, najwyższych poziomów) typów egzystencjalnych i nie jest dla mnie jasne, jaki cel by to w ogóle służyło.
CA McCann

1
Typy egzystencjalne obsługiwane przez GHC to typy, które (bezpośrednio lub pośrednio) mają uniwersalne kwantyfikatory, które, patrząc z „zewnątrz”, występują w pozycji przeciwstawnej. Wykorzystuje to w przybliżeniu tę samą dualność, co logicznej negacji, więc aby mieć takie typy egzystencjalne na najwyższym poziomie, muszą one być podwójnie sprzeczne, używając kodowania podobnego do CPS (jest to równoważność, którą daje Uday Reddy). Należy zauważyć, że kwantyfikatory egzystencjalne w intuicyjnej formie powodują podobne niedogodności z podobnych powodów.
CA McCann,

5

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

X.(X×(XBool))XX.(X×(XBool))

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

Artykuł, który wspominasz o typach egzystencjalnych, jest nieco teoretyczny. Bardziej samouczkiem jest artykuł Cardelli i Wegnera: O zrozumieniu typów, abstrakcji danych i polimorfizmu . Najbardziej zaawansowane podręczniki na temat języków programowania również omawiają typy egzystencjalne. Dobrą książką do sprawdzenia byłyby Podstawy języków programowania Mitchella .

Masz rację, że większość języków programowania nie ma jawnie typów egzystencjalnych. Jednak wiele z nich ma abstrakcyjne typy (lub inne nazwy, takie jak „pakiety” lub „moduły”). Są więc w stanie wyrażać wartości typów egzystencjalnych, nawet jeśli nie traktują takich wartości jako byty pierwszej klasy.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.