Saya sedang mengerjakan kompiler untuk bahasa concatenative dan ingin menambahkan dukungan jenis inferensi. Saya mengerti Hindley-Milner, tetapi saya telah mempelajari teori jenis ketika saya pergi, jadi saya tidak yakin bagaimana mengadaptasinya. Apakah sistem berikut ini masuk akal dan dapat disimpulkan?
Istilah adalah literal, komposisi istilah, kutipan istilah, atau primitif.
Semua istilah menunjukkan fungsi. Untuk dua fungsi dan , , yaitu, penjajaran menunjukkan komposisi terbalik. Literal menunjukkan fungsi niladik.
Istilah selain komposisi memiliki aturan tipe dasar:
Yang terutama absen adalah aturan untuk aplikasi, karena bahasa concatenative tidak memilikinya.
Tipe adalah literal, variabel tipe, atau fungsi dari tumpukan ke tumpukan, di mana tumpukan didefinisikan sebagai tupel bersarang kanan. Semua fungsi secara implisit polimorfik sehubungan dengan "sisa tumpukan".
Ini adalah hal pertama yang tampaknya mencurigakan, tetapi saya tidak tahu persis apa yang salah dengannya.
Untuk membantu keterbacaan dan mengurangi tanda kurung, saya akan menganggap bahwa dalam skema jenis. Saya juga akan menggunakan huruf kapital untuk variabel yang menunjukkan tumpukan, daripada nilai tunggal.
Ada enam primitif. Lima yang pertama cukup berbahaya. dup
mengambil nilai teratas dan menghasilkan dua salinannya. swap
mengubah urutan dua nilai teratas. pop
membuang nilai teratas. quote
mengambil nilai dan menghasilkan kutipan (fungsi) yang mengembalikannya. apply
berlaku kutipan untuk stack.
Combinator terakhir compose
,, harus mengambil dua kutipan dan mengembalikan tipe gabungannya, yaitu, . Dalam bahasa concatenative yang diketik secara statisCat, jenisini sangat mudah.compose
Namun, tipe ini terlalu membatasi: mengharuskan produksi fungsi pertama sama persis dengan konsumsi fungsi kedua. Pada kenyataannya, Anda harus mengasumsikan tipe yang berbeda, lalu menyatukannya. Tetapi bagaimana Anda menulis tipe itu?
Jika Anda membiarkan menunjukkan perbedaan dua jenis, maka saya pikir Anda dapat menulis jenis dengan benar.compose
Ini masih relatif mudah: compose
mengambil fungsi dan satu f 2 : D → E . Hasilnya mengkonsumsi B di atas konsumsi f 2 yang tidak diproduksi oleh f 1 , dan menghasilkan D di atas produksi f 1 yang tidak dikonsumsi oleh f 2 . Ini memberikan aturan untuk komposisi biasa.
Namun, saya tidak tahu bahwa hipotesis ini sebenarnya sesuai dengan apa pun, dan saya telah mengejarnya cukup lama sehingga saya pikir saya salah belok. Mungkinkah itu perbedaan tuple yang sederhana?
Apakah ada sesuatu yang sangat buruk tentang hal ini yang tidak saya lihat, atau apakah saya berada di jalur yang benar? (Saya mungkin salah mengukur beberapa hal ini dan akan menghargai perbaikan di daerah itu juga.)
compose
terlalu ketat? Saya mendapat kesan bahwa ini baik-baik saja seperti ini. (misalnya pembatasantwice
didefinisikan sebagaidup compose apply
, yang mengambil kutipan dan menerapkannya dua kali.[1 +] twice
baik-baik saja: Anda membuat dua fungsi tipe[pop] twice
tidak: jikacompose
tanpa beberapa definisi melingkar.Jawaban:
Berikut peringkat tipe-2
Huruf Yunani digunakan untuk variabel sisa tumpukan untuk kejelasan saja.
Ini mengungkapkan kendala bahwa tumpukan output dari elemen pertama pada tumpukan harus sama dengan tumpukan input dari elemen kedua. Instantiating variabel dengan tepatB karena dua argumen yang sebenarnya adalah cara mendapatkan kendala untuk bekerja dengan baik, daripada mendefinisikan operasi baru, seperti yang Anda usulkan dalam pertanyaan.
Tipe memeriksa tipe-2 tipe tidak dapat diputuskan secara umum, saya percaya, meskipun beberapa pekerjaan telah dilakukan yang memberikan hasil yang baik dalam praktek (untuk Haskell):
Aturan jenis untuk komposisi hanyalah:
Agar sistem tipe berfungsi secara umum, Anda memerlukan aturan spesialisasi berikut:
sumber
dup +
harus memiliki tipe+
has typedup +
, as that does not use compose, as you defined it above.[dup] [+] compose
. But I read