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 pembatasandapat ditangani dengan penyatuan seperti untuk aplikasi dalam seperti di λ-calculus)
twice
didefinisikan sebagai dup compose apply
, yang mengambil kutipan dan menerapkannya dua kali. [1 +] twice
baik-baik saja: Anda membuat dua fungsi tipe. Tetapi [pop] twice
tidak: jika, masalahnya adalah , jadi ekspresi tidak diizinkan meskipun harus valid dan bertipe . Solusinya tentu saja untuk menempatkan kualifikasi di tempat yang tepat, tetapi saya terutama bertanya-tanya bagaimana sebenarnya menulis jenis compose
tanpa beberapa definisi melingkar.