Saya sudah memikirkan sedikit tentang ini. Masalah utama adalah bahwa secara umum, kita tidak tahu seberapa besar nilai tipe polimorfik. Jika Anda tidak memiliki informasi ini, Anda harus mendapatkannya entah bagaimana. Monomorphisation mendapatkan informasi ini untuk Anda dengan mengkhususkan diri pada polimorfisme. Boxing mendapatkan informasi ini untuk Anda dengan meletakkan semuanya ke dalam representasi ukuran yang diketahui.
Alternatif ketiga adalah melacak informasi ini. Pada dasarnya, yang dapat Anda lakukan adalah memperkenalkan jenis yang berbeda untuk setiap ukuran data, dan kemudian fungsi polimorfik dapat didefinisikan atas semua jenis ukuran tertentu. Saya akan membuat sketsa sistem seperti di bawah ini.
JenisKetik konstruktorκSEBUAH: : = N: : =|∀ a : κ .SEBUAH|α|A × B|A + B|A → Br e fSEBUAH|P a d ( k )|μ α : κ .SEBUAH
Di sini, ide tingkat tinggi adalah bahwa jenis tipe memberi tahu Anda berapa banyak kata yang diperlukan untuk meletakkan objek dalam memori. Untuk ukuran apa pun, mudah menjadi polimorfik untuk semua jenis ukuran tertentu. Karena setiap jenis - bahkan yang polimorfik - masih memiliki ukuran yang diketahui, kompilasi tidak lebih sulit daripada untuk C.
Aturan kinding mengubah bahasa Inggris ini menjadi matematika, dan akan terlihat seperti ini:
Γ ⊢ A : n Γ ⊢ B : m
α : n ∈ ΓΓ ⊢ α : nΓ , α : n ⊢ A : mΓ ⊢ ∀ α : n .A : m
Γ ⊢ A : m Γ ⊢ B : nΓ ⊢ A : nΓ ⊢ B : mΓ ⊢ A × B : n + mΓ ⊢ A : nΓ ⊢ B : nGamma ⊢ A + B : n + 1
Γ ⊢ A : mΓ ⊢ B : nΓ ⊢ A → B : 1Γ ⊢ A : nΓ ⊢ r e fA : 1
Γ ⊢ P a d ( k ) : kΓ , α : n ⊢ A : nΓ ⊢ μ α : n .A : n
Jadi forall quantifier mengharuskan Anda memberikan jenis yang Anda jangkau. Demikian juga, pasangan adalah jenis pasangan tanpa kotak, yang hanya menjabarkan sebelah dalam memori (seperti tipe C struct). Disjoint unions mengambil dua nilai dengan ukuran yang sama, dan kemudian menambahkan kata untuk tag diskriminator. Fungsi adalah penutupan, diwakili seperti biasa oleh pointer ke catatan lingkungan dan kode.A × BSEBUAHB
Referensi menarik - pointer selalu satu kata, tetapi mereka dapat menunjuk ke nilai dari berbagai ukuran. Hal ini memungkinkan pemrogram menerapkan
polimorfisme ke objek sewenang-wenang dengan tinju, tetapi tidak mengharuskan
mereka untuk melakukannya. Akhirnya, setelah ukuran eksplisit dimainkan, sering kali berguna untuk memperkenalkan jenis padding, yang menggunakan ruang tetapi tidak melakukan apa-apa. (Jadi jika Anda ingin mengambil persatuan int dan sepasang int, Anda perlu menambahkan pad int pertama, sehingga tata letak objek seragam.)
Tipe rekursif memiliki aturan formasi standar, tetapi perhatikan bahwa kejadian rekursif harus memiliki ukuran yang sama, yang berarti Anda biasanya harus menempelkannya dalam sebuah pointer untuk membuat kinding bekerja. Misalnya, tipe data daftar dapat direpresentasikan sebagai
μ α : 1.r e f( P a d ( 2 ) + i n t × α )
Jadi ini menunjuk ke nilai daftar kosong, atau sepasang int dan pointer ke daftar tertaut lainnya.
Jenis memeriksa sistem seperti ini juga tidak terlalu sulit; algoritma dalam makalah ICFP saya dengan Joshua Dunfield, Pengetikan Dua Arah Lengkap dan Mudah untuk Polimorfisme Peringkat Tinggi berlaku untuk kasus ini dengan hampir tidak ada perubahan.