Kutusuz tiplere göre daha üst düzey polimorfizm


10

Hindley – Milner tabanlı tür çıkarım ile, varsayılan olarak türlerin kutusundan çıkarıldığı bir dilim var. Esas olarak varoluşçu tiplerle çalışmak için daha üst düzey bir polimorfizm eklemek istiyorum.

Sanırım bu türleri nasıl kontrol edeceğimi anlıyorum ama derlerken ne yapacağımdan emin değilim. Şu anda, kutulanmamış değerlerle çalışabilmeleri için C ++ şablonları gibi uzmanlıklar oluşturarak polimorfik tanımları derliyorum. Örnegin, f<T>programin yalnizca çagiriyorsa f<Int32>ve f<Char>derlenen programda yalnizca bu uzmanliklar görünürse bir tanimlama verilir . (Şimdilik tüm program derlemesini varsayıyorum.)

Ancak bir polimorfik işlevi argüman olarak geçirirken, statik olarak doğru uzmanlığı nasıl üretebileceğimi göremiyorum, çünkü fonksiyon çalışma zamanında seçilebilir. Kutulu bir sunum kullanmaktan başka seçeneğim yok mu? Yoksa sorunun bir yolu var mı?

İlk düşüncem nasılsa kodlamak rank- oldu n rank 1 olarak polimorfizmi ama yapıcı mantıkta bir formül mutlaka bir prenex normal formu olmadığı için genel olarak mümkün olduğuna inanmıyorum.


Bir alternatif, bir fonksiyonun ve kelimelerin hafızadaki işaretlerinin işaretçi olduğu bitmap'leri depolayarak gereken boks miktarını azaltmaktır. Daha sonra bir polimorfik fonksiyon / yapı aslında bir işaretçi veya keyfi bir veri sözcüğü üzerinde polimorfiktir ve yapılar son alanlarını (polimorfik olsa bile) satır içinde saklayabilir. Bu bitmapler, toplamsız türler için tagwords ihtiyacını önlemek için GC tarafından da kullanılabilir.
fread2281

@ fread2281: Aslında dilin eski bir versiyonunda böyle bir şey yapardım. Şu anda toplam olmayan türler için etiket oluşturmuyorum ve GC yok. Bence bu Neel K'nin yaklaşımıyla da uyumlu.
Jon Purdy

Yanıtlar:


6

Bunun hakkında biraz düşündüm. Asıl mesele, genel olarak, polimorfik tipin bir değerinin ne kadar büyük olduğunu bilmiyoruz. Bu bilgiye sahip değilseniz, bir şekilde almanız gerekir. Monomorfizasyon, polimorfizmi uzmanlaştırarak bu bilgiyi sizin için alır. Boks, her şeyi bilinen bir boyutta temsil ederek bu bilgiyi sizin için alır.

Üçüncü bir alternatif de bu bilgileri çeşitlerde takip etmektir. Temel olarak, yapabileceğiniz her veri boyutu için farklı bir tür tanıtmaktır ve daha sonra polimorfik fonksiyonlar belirli bir boyutun tüm tipleri üzerinde tanımlanabilir. Aşağıda böyle bir sistemi çizeceğim.

Çeşitleriκ:: =nTip yapıcılarbir:: =bir:κ.bir|α|birxB|bir+B|birB|refbir|Pbird(k)|μα:κ.bir

Burada, üst düzey fikir, bir türün size bir nesneyi hafızaya yerleştirmek için kaç kelime gerektiğini anlatmasıdır. Herhangi bir boyut için, belirli boyuttaki tüm tiplerde polimorfik olmak kolaydır. Her tür - hatta polimorfik olanlar - hala bilinen bir boyuta sahip olduğundan, derleme C için olduğundan daha zor değildir.

Sıralama kuralları bu İngilizceyi matematiğe dönüştürür ve şöyle görünmelidir: ΓA : n ΓB : m

α:nΓΓα:nΓ,α:nbir:mΓα:n.bir:m
ΓA : m ΓB : n
Γbir:nΓB:mΓbirxB:n+mΓbir:nΓB:nΓbir+B:n+1
Γbir:mΓB:nΓbirB:1Γbir:nΓrefbir:1
ΓPbird(k):kΓ,α:nbir:nΓμα:n.bir:n

birxBbirB

Referanslar ilginçtir - işaretçiler her zaman bir kelimedir, ancak herhangi bir boyuttaki değerlere işaret edebilirler. Bu, programcıların boks yaparak keyfi nesnelere polimorfizm uygulamasını sağlar , ancak bunu yapmalarını gerektirmez . Son olarak, açık boyutlar oynandıktan sonra, alan kullanan ancak hiçbir şey yapmayan bir dolgu türü tanıtmak genellikle yararlıdır. (Eğer bir int ve bir çift ints ayrık birliği almak istiyorsanız, ilk int dolgu eklemek gerekir, böylece nesne düzeni düzgün.)

Özyinelemeli türler standart oluşum kuralına sahiptir, ancak özyinelemeli olayların aynı boyutta olması gerektiğine dikkat edin, bu da türlemenin çalışması için bunları genellikle bir işaretçiye yapıştırmanız gerektiği anlamına gelir. Örneğin, liste veri türü şu şekilde temsil edilebilir:

μα:1.ref(Pbird(2)+benntxα)

Bu, boş bir liste değerine veya bir çift int ve bağlı başka bir listeye işaretçi anlamına gelir.

Bunun gibi sistemler için tip kontrolü de çok zor değildir; Joshua Dunfield ile ICFP makalemdeki algoritma, Yüksek Sıralama Polimorfizmi için Tam ve Kolay Çift Yönlü Tipik Kontrol , neredeyse hiç değişiklik yapılmadan bu durum için geçerlidir.


Güzel, bence bu kullanım durumumu düzgün bir şekilde kapsıyor. Değer temsilleri (GHC'ler *vs. gibi) hakkında akıl yürütmek için çeşit kullanmanın farkındaydım #, ancak bunu bu şekilde yapmayı düşünmemiştim. Yüksek dereceli niceleyicileri bilinen büyüklükteki türlerle sınırlamak mantıklı görünüyor ve bence bu da gerçek türü bilmeye gerek kalmadan boyut başına uzmanlıklarını statik olarak üretmeme izin verecek. Şimdi, o makaleyi yeniden okuma zamanı. :)
Jon Purdy

1

Bu bir derleme problemine "teorik bilgisayar bilimi" probleminden daha yakın gibi görünüyor, bu yüzden muhtemelen başka bir yerde sormak daha iyi.

Genel durumda, aslında, kutulu bir temsil kullanmaktan başka bir çözüm olmadığını düşünüyorum. Ancak, pratikte durumunuzun özelliklerine bağlı olarak birçok farklı alternatif seçenek olmasını bekliyorum.

Örneğin, kutulanmamış argümanların düşük seviyeli temsili genellikle tamsayı veya benzer, kayan nokta veya işaretçi gibi çok az sayıda alternatif olarak kategorize edilebilir. Bu nedenle, bir işlev için f<T>, belki de sadece 3 farklı kutulanmamış uygulama üretmeniz gerekir ve polimorfik olanı bu 3 fonksiyonun bir parçası olarak temsil edebilirsiniz, bu nedenle Int32'ye örnek oluşturmak sadece grubun ilk öğesini seçmektir ...


Yardımın için teşekkürler. Nereden soracağımdan gerçekten emin değildim, çünkü bir derleyici yüksek seviyeli teoriden düşük seviyeli mühendisliğe kadar uzanıyor, ancak buradaki insanların bazı fikirleri olacağını düşündüm. Boks gerçekten de buradaki en esnek yaklaşım olabilir gibi görünüyor. Cevabınızı okuduktan ve üzerinde daha fazla düşündükten sonra, ortaya koyabildiğim diğer makul çözüm, bazı esneklikten vazgeçmek ve polimorfik argümanların statik olarak bilinmesini, örneğin bunları tür parametreleri olarak geçirerek gerektirmektir. Tamamen değiş tokuş. : P
Jon Purdy

4
OP'nin sorusu, Damas-Hindley-Milner daha yüksek rütbe türleriyle genişletildiğinde tip çıkarımının nasıl yapılacağı gibi mükemmel geçerli TCS problemlerini içerir. Genel olarak sıra-2 polimorfizmi karar verilebilir tip çıkarımına sahiptir, ancak sıra k> 2 türü çıkarım için karar verilemez. Damas-Hindley-Milner kısıtlamasının bunu değiştirip değiştirmediğini bilmiyorum. Son olarak, modern derleyicilerin yaptığı hemen hemen her şey TCS'nin bir parçası olmalıdır, ancak genellikle derleyici uygulayıcıları teorisyenlerin önünde olduğu için değildir.
Martin Berger
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.