Jenis sebagai Warga negara kelas satu

10

Berasal dari latar belakang C ++ saya tidak mengerti mengapa seseorang membutuhkan tipe / tipe ekspresi sebagai warga negara kelas satu? Satu-satunya bahasa yang saya tahu yang mendukung fitur ini adalah Aldor.

Adakah yang punya literatur tentang tipe sebagai warga negara kelas satu atau tahu beberapa alasan mengapa ini berguna?

paul98
sumber
3
Idris juga memilikinya.
ThreeFx
1
Apakah Anda bertanya tentang konsep umum "type is a value" (disebut "reflection" atau "metaclasses" dalam berbagai bahasa) atau tentang konsep ekspresi tipe yang lebih spesifik?
svick
1
@vick Saya tertarik pada yang terakhir. Sayangnya saya belum menemukan banyak hal umum tentang ekspresi tipe sehingga akan lebih baik jika Anda bisa menyarankan beberapa literatur.
paul98

Jawaban:

11

Tipe kelas pertama memungkinkan sesuatu yang disebut pengetikan dependen . Ini memungkinkan programmer untuk menggunakan nilai tipe pada level tipe. Misalnya, tipe semua pasangan bilangan bulat adalah tipe biasa, sedangkan pasangan semua bilangan bulat dengan angka kiri lebih kecil dari angka kanan adalah tipe dependen. Contoh pengantar standar dari ini adalah daftar panjang disandikan (biasanya disebut Vectordalam Haskell / Idris). Kode pseudo berikut adalah campuran dari Idris dan Haskell.

-- a natural number
data Nat = Zero | Successor Nat

data Vector length typ where
  Empty : Vector Zero typ
  (::)   : typ -> Vector length typ -> Vector (Successor length) typ

Bagian kode ini memberi tahu kita dua hal:

  • Daftar kosong memiliki panjang nol.
  • consing elemen ke daftar membuat daftar panjang n + 1

Ini terlihat sangat mirip dengan konsep lain dengan 0 dan n + 1, bukan? Saya akan kembali ke sana.

Apa yang kita dapat dari ini? Kami sekarang dapat menentukan properti tambahan dari fungsi yang kami gunakan. Misalnya: Properti penting appendadalah bahwa panjang daftar yang dihasilkan adalah jumlah dari panjang dari dua daftar argumen:

plus : Nat -> Nat -> Nat
plus          Zero n = n
plus (Successor m) n = Successor (plus m n)

append : Vector n a -> Vector m a -> Vector (plus n m) a
append Empty  ys = ys
append (x::xs) ys = x :: append xs ys

Namun secara keseluruhan teknik ini tampaknya tidak semua berguna dalam pemrograman sehari-hari. Bagaimana ini berhubungan dengan soket, POST/ GETpermintaan dan sebagainya?

Yah itu tidak (setidaknya bukan tanpa usaha yang cukup). Tapi itu bisa membantu kita dengan cara lain:

Tipe dependen memungkinkan kita untuk merumuskan invarian dalam kode - aturan seperti bagaimana suatu fungsi harus berperilaku. Dengan menggunakan ini, kami mendapatkan keamanan tambahan tentang perilaku kode, mirip dengan kondisi sebelum dan sesudah Eiffel. Ini sangat berguna untuk pembuktian teorema otomatis, yang merupakan salah satu kegunaan yang mungkin untuk Idris.

Kembali ke contoh di atas, definisi daftar panjang-dikodekan menyerupai konsep matematika induksi . Di Idris, Anda sebenarnya dapat merumuskan konsep induksi pada daftar seperti berikut:

              -- If you can supply the following:
list_induction : (Property : Vector len typ -> Type) -> -- a property to show
                  (Property Empty) -> -- the base case
                  ((w : a) -> (v : Vector n a) ->
                      Property v -> Property (w :: v)) -> -- the inductive step
                  (u : Vector m b) -> -- an arbitrary vector
                  Property u -- the property holds for all vectors

Teknik ini terbatas pada bukti konstruktif, tetapi tetap sangat kuat. Anda dapat mencoba menulis secara appendinduktif sebagai latihan.

Tentu saja, tipe dependen hanyalah satu penggunaan tipe kelas satu, tapi ini bisa dibilang salah satu yang paling umum. Penggunaan tambahan termasuk, misalnya, mengembalikan tipe tertentu dari fungsi berdasarkan argumennya.

type_func : Vector n a -> Type
type_func Empty = Nat
type_func v     = Vector (Successor Zero) Nat

f : (v : Vector n a) -> type_func v
f Empty = 0
f vs    = length vs :: Empty

Ini adalah contoh yang tidak masuk akal, tetapi ini menunjukkan sesuatu yang tidak dapat Anda tiru tanpa tipe kelas satu.

ThreeFx
sumber