Ich habe ein bisschen darüber nachgedacht. Das Hauptproblem ist, dass wir im Allgemeinen nicht wissen, wie groß der Wert des polymorphen Typs ist. Wenn Sie diese Informationen nicht haben, müssen Sie sie irgendwie bekommen. Die Monomorphisierung erhält diese Informationen für Sie, indem sie sich auf den Polymorphismus spezialisiert. Boxing erhält diese Informationen für Sie, indem es alles in eine Darstellung bekannter Größe bringt.
Eine dritte Alternative besteht darin, diese Informationen in den Arten zu verfolgen. Grundsätzlich können Sie für jede Datengröße eine andere Art einführen, und dann können polymorphe Funktionen für alle Typen einer bestimmten Größe definiert werden. Ich werde ein solches System unten skizzieren.
KindsType constructorsκA::=n::=|∀a:κ.A|α|A×B|A+B|A→BrefA|Pad(k)|μα:κ.A
Hier besteht die übergeordnete Idee darin, dass die Art eines Typs angibt, wie viele Wörter erforderlich sind, um ein Objekt im Speicher auszulegen. Für jede gegebene Größe ist es einfach, über alle Arten dieser bestimmten Größe polymorph zu sein. Da jeder Typ - auch polymorphe - immer noch eine bekannte Größe hat, ist die Kompilierung nicht schwieriger als bei C.
α:n∈ΓΓ⊢α:nΓ,α:n⊢A:mΓ⊢∀α:n.A:m
Γ⊢A:nΓ⊢B:mΓ⊢A×B:n+mΓ⊢A:nΓ⊢B:nΓ⊢A+B:n+1
Γ⊢A:mΓ⊢B:nΓ⊢A→B:1Γ⊢A:nΓ⊢refA:1
Γ⊢Pad(k):kΓ,α:n⊢A:nΓ⊢μα:n.A:n
A×BAB
Referenzen sind interessant - Zeiger sind immer ein Wort, können aber auf Werte beliebiger Größe verweisen. Auf diese Weise können Programmierer implementieren
Polymorphismus auf beliebige Objekte durch Boxen, aber nicht erforderlich ,
sie so zu tun. Sobald explizite Größen im Spiel sind, ist es oft nützlich, einen Polstertyp einzuführen, der Platz beansprucht, aber nichts tut. (Wenn Sie also die disjunkte Vereinigung eines int und eines Int-Paares verwenden möchten, müssen Sie das erste int auffüllen, damit das Objektlayout einheitlich ist.)
Rekursive Typen haben die Standardformationsregel. Beachten Sie jedoch, dass rekursive Vorkommen dieselbe Größe haben müssen. Dies bedeutet, dass Sie sie normalerweise in einen Zeiger stecken müssen, damit die Sortierung funktioniert. Beispielsweise könnte der Listendatentyp als dargestellt werden
μα:1.ref(Pad(2)+int×α)
Dies zeigt also auf einen leeren Listenwert oder ein Paar aus einem int und einem Zeiger auf eine andere verknüpfte Liste.
Die Typprüfung für solche Systeme ist ebenfalls nicht sehr schwierig. Der Algorithmus in meinem ICFP- Artikel mit Joshua Dunfield, Vollständige und einfache bidirektionale Typprüfung für höherrangigen Polymorphismus, gilt für diesen Fall nahezu unverändert .