Gibt es aus Neugier Sprachen, mit denen Sie Typen arithmetisch festlegen können, um neue Typen zu erstellen? So etwas wie:
interface A {
void a();
void b();
}
interface B {
void b();
void c();
}
interface C = A & B; // has b()
interface D = A | B; // has a(), b() and c()
interface E = (A & B) ^ B; // has c()
Ich weiß, dass diese Ideen in einigen Sprachen ausgedrückt werden können (dh Java hat List<Comparable & Serializable>
für die Vereinigung der Schnittstellen), aber ich habe noch nie von einer Sprache gehört, die Typarithmetik unterstützt. Vielen Dank!
programming-languages
type-systems
Haldean Brown
quelle
quelle
CanWriteAndCompare extends Serializable, Comparable {}
), und ich habe darüber nachgedacht, wie ich dies verallgemeinern kann.A
oder ein nehmen kannB
, mit zwei Implementierungen, die genau gleich aussehen. In der Methode rufe ich eine polymorphe Methode auf, die einA
oder ein annehmen kannB
, daher sind die Implementierungen gleich, aber da ich zwei verschiedene Typen verwenden muss, benötige ich zwei Implementierungen. Das wäre einfacher, wenn ich es könntemyMethod(A | B aOrB)
.Or
Operation kann durch Mehrfachvererbung emuliert werden.Antworten:
Tangente ( Spezifikation 0,3 ) verwendet etwas Ähnliches. (Haftungsausschluss: Dies ist mein eigenes kleines Forschungsprojekt)
Derzeit
with
fungiert er als Gewerkschaftsoperator, der die Vererbung modelliert, obwohl Pragmatismus sie nicht kommutativ gemacht hat. Sobald Sie Implementierungen in Methoden eingeführt haben, ist eine strikte Vereinigung gleichnamiger Methoden oft nicht das, was Sie wollen, und es ist sowieso unmöglich, sie richtig zu machen.intersect
Es wird unterstützt, dass Modelle Inferenzen für etwas eingeben,foo(T,T)
bei dem die Parameter unterschiedlich sind.Ergänzungen waren interessant, führten jedoch zu Teiltypen, deren korrekte Aufnahme nicht so nützlich und / oder mühsam schien - sie sind also nicht enthalten.
Ich weiß, dass es einige andere Forschungssprachen gibt, die mir begegnet sind und die etwas Ähnliches hatten, aber ich kann mich im Moment nicht an sie erinnern. Das Hauptproblem ist, dass die Dinge ohne strukturelle Typisierung nicht wirklich nützlich sind, was selbst nicht besonders beliebt ist. Das andere ist, dass Sie eine Art (Typ von Typen) benötigen, um den konstruierten Typ zu speichern, oder es ist nur eine Abkürzung für etwas, das ohne diese Fähigkeit nicht besonders idiomatisch ist. Und das ist weitaus seltener als strukturelles Tippen.
Es ist voreingenommen und es ist nicht viel, aber da ist es.
quelle
Ja, Ceylon ist eine Sprache mit Ad-hoc-Vereinigungs- und Kreuzungstypen, wie in diesem Kapitel der Ceylon-Tour beschrieben:
Es ist erstaunlich, wie viele coole Redewendungen man daraus macht. Hier ist ein interessantes Beispiel, das ich kürzlich gebloggt habe . Und hier ist eine kurze Präsentation, in der ich schnell einige einfache Redewendungen beschönige .
Noch besser ist, dass Vereinigungs- / Schnittpunkttypen das "fehlende Glied" sind, das die Inferenz generischer Typargumente in Ceylon wirklich richtig macht, im Gegensatz zu anderen Sprachen, die Subtyp und parametrischen Polymorphismus kombinieren.
Beachten Sie, dass diese Art der "Typarithmetik", wie Sie sie beschrieben haben, Einschränkungen unterliegt. Zum Beispiel können Sie keinen Set-Complement-Operator auf Typebene haben, zumindest nicht ohne Unentscheidbarkeit.
HTH
quelle
Scala unterstützt es teilweise (Schnittpunkte, aber keine Gewerkschaften), und jede Sprache mit struktureller Untertypisierung (ich denke, OCaml ist ein Beispiel) oder ein Typsystem, das leistungsfähig genug ist, um dies zu emulieren (Haskell ist ein klassisches), verfügt über vollständige "Typen als Mengen" "Fähigkeiten, zumindest innerhalb des Fragments seines Typsystems, das solche Dinge akzeptiert (relevant, wenn es ala HList / OOHaskell emuliert wird).
Da ich OCaml nicht sehr gut kenne, gebe ich den Teil Ihres Beispiels an, der in Scala funktioniert:
Eine Version für Haskell hängt von dem von Ihnen verwendeten Aufzeichnungssystem ab und ist wahrscheinlich etwas umständlich, da sie eher emuliert als nativ unterstützt wird.
Soweit ich weiß, sind in Ceylon sowohl Schnitt- als auch Vereinigungstypen mit voller Leistung in die Sprache integriert, sodass Sie vermutlich ein "xor" auf Textebene in Bezug auf diese codieren können.
quelle
Java unterstützt in einigen Kontexten Schnittpunkte von Schnittstellentypen, obwohl dies meines Erachtens die Erstellung von Variablen für Schnittpunkttypen nicht zulässt. Schnittpunkttypen können beispielsweise bei Verwendung des
? :
Operators ins Spiel kommen . Wenn der zweite und der dritte Operand für diesen Operator nicht verwandte Schnittstellen sind, die von überlappenden Schnittstellensätzen erben, ist das Ergebnis des Operators der Satz von Schnittstellen, die beiden gemeinsam sind.quelle
Mit Common Lisp können Sie neue Typen mit den Operatoren ,, und definieren (siehe Typspezifizierer
not
, die kombiniert werden ).and
or
quelle