I tipi universali sono un sottotipo o un caso speciale di tipi esistenziali?


20

Vorrei sapere se un tipo : universalmente quantificato è un sottotipo, oppure caso speciale, di tipo quantificato con la stessa firma:Ta

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

Direi "sì": se qualcosa è vero "per tutte le X" ( ), allora deve anche essere vero "per alcune X" ( ). Cioè, un'istruzione con ' ' è semplicemente una versione più limitata della stessa istruzione con ' ':XX

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

Sbaglio da qualche parte?

Contesto: perché lo sto chiedendo?

Sto studiando i tipi esistenziali per capire perché e come "I tipi astratti [di dati] hanno un tipo esistenziale" . Non riesco a capire bene questo concetto solo dalla teoria; Ho bisogno anche di esempi concreti.

Sfortunatamente, è difficile trovare buoni esempi di codice perché la maggior parte dei linguaggi di programmazione ha solo un supporto limitato per i tipi esistenziali. (Ad esempio, i caratteri jolly di Haskellforall o Java? ). D'altra parte, i tipi universalmente quantificati sono supportati da molte lingue recenti tramite "generici".

Quel che è peggio, anche i generici sembrano facilmente confondersi con i tipi esistenziali , rendendo ancora più difficile distinguere i tipi esistenziali dai tipi universali. Sono curioso di sapere perché questo disordine si verifica così facilmente. Una risposta a questa domanda potrebbe spiegarlo: se i tipi universali sono davvero solo un caso speciale di tipi esistenziali, non c'è da meravigliarsi che i tipi generici, ad esempio Java List<T>, possano essere interpretati in entrambi i modi.


1
Qual è anche la differenza tra universale ed esistenziale?

Matematicamente parlando, hai ragione: se forall x. P(x)allora exists x. P(x). Se i sistemi di tipo ne tengono conto quando si controllano i tipi ... Non ne ho idea. +1 per una domanda interessante.

1
@deinan: se P (x) non vale per nessuna x , allora sicuramente ∀xP (x) non regge. Quello che probabilmente intendevi è quando non ci sono x , ovvero ∀x∈XP (x) non implica ∃x∈XP (x) se X = ∅ .

1
... E nota che se questi vengono riscritti senza notazione prestabilita, appariranno diversi: ∀xx∈X⇒P (x) vs. ∃xx∈X & P (x) e che ∃xx∈X⇒P (x) sarà banalmente soddisfatta da qualsiasi x non da x .

1
Bella domanda. In Haskell è certamente vero che un valore di tipo (forall b. Show b => b) può essere passato a una funzione che accetta a (forall b. B), ma non viceversa, implicando la sostituibilità che ti aspetteresti da una relazione di sottotipo. Ma ovviamente quando parli di tipi dovresti menzionare il sistema di tipi che stai osservando, in particolare se hai in mente un'algebra di tipo formale per la tua semantica ...

Risposte:


10

Innanzitutto, da un punto di vista matematico, non implica x : T , P ( x ) . L'implicazione vale se e solo se T non è vuoto. Tuttavia, nei linguaggi di programmazione, è raro trattare tipi vuoti (anche se succede).x:T,P(x)x:T,P(x)T

Sempre da un punto di vista matematico, anche quando , i due non sono gli stessi. Se dai ai tipi una semantica fissa, allora T a è un superset di T e , non lo stesso tipo. (In realtà non è un superset; è vicino all'isomorfo di un superset.)(x:T,P(x))(x:T,P(x))TaTe

Avviciniamoci alla teoria del linguaggio di programmazione e vediamo cosa significano realmente questi tipi. è di tipo universale: se si dispone di un valore Una di quel tipo, è possibile costruire A ( M ) per qualsiasi M : X . In particolare, se hai M 1 e M 2 entrambi di tipo X , puoi costruire A ( MTa=X.{a:X,f:Xbool}AA(M)M:XM1M2X e A ( M 2 ) . In sostanza (e possibilmente in effetti, a seconda della lingua) T a è una funzione dai tipi ai termini. Come tale, il tipo universale fornisce laparametrizzazione deltipo: un valore che funziona per tutti i tipi. I tipi universali sono al centro delpolimorfismo.A(M1)A(M2)Ta

Il esistenziale di tipo è una bestia abbastanza diversa. Dato un valore B di tipo T e , esiste solo un termine N : X tale che π 1 ( B ) = N , e per questo termine π 2 ( B ) = { a : N , f :Te=X.{a:X,f:Xbool}BTeN:Xπ1(B)=N . Il tipo esistenziale fornisce un modo per nascondere la natura di N ; sta dicendo: “Esiste un tipo! Ma non ti dirò quale! ”. Pertanto, il tipo esistenziale fornisce l'astrazione deltipo: un valore nascosto specifico. I tipi esistenziali sono al centro deisistemidimoduli.π2(B)={a:N,f:Nbool}N

Non farti ingannare da Haskell forall: nonostante il suo nome, è una forma di quantificatore esistenziale.

Per lo sfondo, consiglio vivamente i tipi e i linguaggi di programmazione (i capitoli 23 e 24 discutono rispettivamente i tipi universali e quelli esistenziali). Fornirà un utile background per comprendere gli articoli di ricerca.


1
Un piccolo cavillo, e piuttosto tardi, quello di Haskell forallè davvero un quantificatore universale nel contesto originale della quantificazione implicita che rende esplicito, vale a dire la visualizzazione di tipi polimorfici "dall'esterno" per definizioni di alto livello. All'interno di una tale definizione, quando si manipolano gli argomenti, i tipi polimorfici sono effettivamente esistenziali; ogni variabile di tipo è associata a un certo tipo, ma non sappiamo (e non possiamo) sapere quale sia quel tipo. Per quanto ne sappia, nessuna implementazione di Haskell supporta tipi esistenziali reali (grezzi, di livello superiore) e non mi è chiaro quale scopo possa servire.
CA McCann

1
I tipi esistenziali supportati da GHC sono tipi che (direttamente o indirettamente) hanno quantificatori universali che, visti dall'esterno, si presentano in posizione contraddittoria. Questo utilizza all'incirca la stessa dualità di quella della negazione logica, quindi per avere tali tipi esistenziali ai massimi livelli devono essere doppiamente contraddittori, usando una codifica simile a CPS (questa è l'equivalenza di Uday Reddy). Si noti che i quantificatori esistenziali in intuizionismo presentano inconvenienti simili per ragioni simili.
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]

L'articolo che citi per tipi esistenziali è un po 'teorico. Un altro articolo tutorial è l'articolo di Cardelli e Wegner: comprensione dei tipi, astrazione dei dati e polimorfismo . La maggior parte dei libri di testo avanzati sui linguaggi di programmazione avrebbe anche qualche discussione sui tipi esistenziali. Un buon libro da cercare sarebbero le basi di Mitchell dei linguaggi di programmazione .

Hai ragione sul fatto che la maggior parte dei linguaggi di programmazione non ha esplicitamente tipi esistenziali. Tuttavia, molti hanno tipi astratti (o con qualche altro nome come "pacchetti" o "moduli"). Pertanto, sono in grado di esprimere valori di tipi esistenziali, anche se non trattano tali valori come entità di prima classe.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.