Apakah tipe universal adalah sub-tipe, atau kasus khusus, dari tipe eksistensial?

20

Saya ingin tahu apakah tipe dikuantifikasi secara universal : adalah sub-tipe, atau kasus khusus, dari tipe dikuantifikasi secara dengan tanda tangan yang sama:T a = X : { a X , f : X { T , F } }TSebuah

TSebuah=X:{SebuahX,f:X{T,F}}
T e = X : { a X , f : X { T , F } }Te
Te=X:{SebuahX,f:X{T,F}}

Saya akan mengatakan "ya": Jika ada sesuatu yang benar "untuk semua X" ( ), maka itu juga harus benar "untuk beberapa X" ( ). Artinya, pernyataan dengan ' ' hanyalah versi yang lebih terbatas dari pernyataan yang sama dengan ' ':X X , P ( X ) ?XX

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

Apakah saya salah di suatu tempat?

Latar Belakang: Mengapa saya menanyakan hal ini?

Saya mempelajari tipe eksistensial untuk memahami mengapa dan bagaimana "Abstrak [Data] Jenis Memiliki Tipe Eksistensial" . Saya tidak bisa memahami konsep ini hanya dari teori; Saya perlu contoh nyata juga.

Sayangnya, contoh kode yang baik sulit ditemukan karena sebagian besar bahasa pemrograman hanya memiliki dukungan terbatas untuk jenis eksistensial. (Misalnya, Haskellforall , atau wildcard Java? .) Di sisi lain, tipe yang dikuantifikasi secara universal didukung oleh banyak bahasa terkini melalui "generik".

Yang lebih buruk, obat generik tampaknya mudah bercampur dengan tipe eksistensial , juga, membuatnya lebih sulit untuk membedakan eksistensial dari tipe universal. Saya ingin tahu mengapa percampuran ini terjadi begitu mudah. Sebuah jawaban untuk pertanyaan ini mungkin menjelaskannya: Jika tipe universal memang hanya merupakan kasus khusus dari tipe eksistensial, maka tidak mengherankan bahwa tipe generik, misalnya Java List<T>, dapat ditafsirkan dengan cara baik.

Raphael
sumber
1
Apa perbedaan antara universal dan eksistensial?
Secara matematis, Anda benar: Kalau forall x. P(x)begitu exists x. P(x). Apakah sistem tipe mempertimbangkan hal ini saat memeriksa tipe ... Saya tidak tahu. +1 untuk pertanyaan yang menarik.
1
@deinan: Jika P (x) tidak tahan untuk x , tentu saja ∀xP (x) tidak tahan. Apa yang mungkin Anda maksud adalah ketika tidak ada x , yaitu ∀x∈XP (x) tidak menyiratkan ∃x∈XP (x) jika X = ∅ .
1
... Dan perhatikan, bahwa jika itu ditulis ulang tanpa notasi yang diset, mereka akan terlihat berbeda: ∀xx∈X⇒P (x) vs ∃xx∈X & P (x) dan ∃xx∈X⇒P (x) akan sepele puas dengan setiap x tidak dari x .
1
Pertanyaan keren Dalam Haskell memang benar bahwa nilai tipe (forall b. Show b => b) dapat diteruskan ke fungsi yang mengambil (forall b. B), tetapi tidak sebaliknya, menyiratkan kemampuan pengganti yang Anda harapkan dari hubungan subtyping. Tetapi tentu saja ketika Anda berbicara tentang jenis, Anda harus menyebutkan sistem jenis yang Anda lihat, terutama jika Anda memiliki aljabar jenis formal dalam pikiran untuk semantik Anda ...

Jawaban:

10

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

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

TSebuah=X.{Sebuah:X,f:XbHaiHail}SEBUAHSEBUAH(M.)M.:XM.1M.2XSEBUAH(M.1)SEBUAH(M.2)TSebuah

Te=X.{Sebuah:X,f:XbHaiHail}BTeN:Xπ1(B)=Nπ2(B)={Sebuah:N,f:NbHaiHail}N

Jangan disesatkan oleh Haskell forall: meskipun namanya, itu adalah bentuk kuantifikasi eksistensial.

Untuk latar belakang, saya sangat merekomendasikan Jenis dan Bahasa Pemrograman (bab 23 dan 24 masing-masing membahas tipe universal dan tipe eksistensial). Ini akan memberikan latar belakang yang berguna untuk memahami artikel penelitian.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Satu minor, dan agak terlambat, berdalih - Haskell forallmemang merupakan kuantifier universal dalam konteks asli kuantifikasi implisit yang dibuatnya eksplisit, yaitu melihat tipe polimorfik "dari luar" untuk definisi tingkat atas. Pada "bagian dalam" dari definisi semacam itu, ketika memanipulasi argumen, tipe polimorfik secara efektif eksistensial; setiap variabel tipe terikat ke beberapa tipe, tetapi kami tidak (dan tidak bisa) tahu apa tipe itu. Sepengetahuan saya, tidak ada implementasi Haskell yang mendukung tipe eksistensial sejati (mentah, tingkat atas), dan tidak jelas bagi saya tujuan apa yang bahkan dapat digunakan.
CA McCann
1
Tipe eksistensial yang didukung oleh GHC adalah tipe yang (langsung atau tidak langsung) memiliki pembilang universal yang, dilihat dari "luar", terjadi dalam posisi contravarian. Ini menggunakan dualitas yang kira-kira sama dengan negasi logis, sehingga untuk memiliki tipe eksistensial di tingkat atas, mereka harus dua kali lebih berkebalikan, menggunakan pengkodean seperti CPS (ini adalah kesetaraan yang diberikan Uday Reddy). Perhatikan bahwa pembilang eksistensial dalam intuitionistic menghadirkan ketidaknyamanan yang serupa untuk alasan yang sama.
CA McCann
5

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

X.(X×(XBHaiHail))XX.(X×(XBHaiHail))

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

Artikel yang Anda sebutkan untuk tipe eksistensial sedikit teoretis. Artikel tutorial lainnya adalah makalah Cardelli dan Wegner: Tentang memahami tipe, abstraksi data, dan polimorfisme . Sebagian besar buku teks canggih tentang bahasa pemrograman juga akan membahas beberapa jenis eksistensial. Buku yang bagus untuk dilihat adalah Yayasan Bahasa Pemrograman Mitchell .

Anda benar bahwa sebagian besar bahasa pemrograman tidak memiliki tipe eksistensial secara eksplisit. Namun, banyak yang memiliki tipe abstrak (atau dengan nama lain seperti "paket" atau "modul"). Jadi, mereka mampu mengekspresikan nilai tipe eksistensial, meskipun mereka tidak memperlakukan nilai-nilai seperti entitas kelas satu.

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

Uday Reddy
sumber