Wie unterscheiden sich existenzielle Typen von Schnittstellen?

11

Angesichts des existenziellen Typs

T = X.{op₁:X, op₂:Xboolean}

und diese generische Java-Schnittstelle:

interface T<X> {
    X op₁();
    boolean op₂(X something);
}

Was sind die grundlegenden Unterschiede zwischen dem existenziellen Typ und der Java-Schnittstelle?

Offensichtlich gibt es syntaktische Unterschiede und die Objektorientierung von Java (die auch Details wie versteckte thisParameter usw. enthält). Diese interessieren mich weniger als vielmehr konzeptionelle und semantische Unterschiede. Wenn jedoch jemand einige Feinheiten (wie den Unterschied in der Notation zwischen Tvs. T<X>) beleuchten möchte, wäre dies ebenfalls wünschenswert.

stakx
quelle

Antworten:

4

Hmm ... Diese Definition sieht einem Haskell-Beispiel sehr ähnlich, das ich vor langer Zeit gesehen habe.

{-# LANGUAGE ExistentialQuantification #-}
data X = forall a . X { value :: a, viewValue :: a -> String }
instance Show X where show (X { value = x, viewValue = f}) = f x
sample :: [X]
sample = [X 3 show, X "abc" show, X 3.14 show]

Wenn der Konstruktor Xangewendet wird, wird ∀ tatsächlich zu ∃. Beachten Sie, dass valueSie beim Herausnehmen den Typ nicht kennen und einen leeren Satz von Operationen darüber haben. Aber da viewValuees irgendwie kohärent ist value, kann es darauf angewendet werden.

Ich denke, der Hauptunterschied von Java, den interfaceSie vorgeschlagen haben, ist die Tatsache, dass Sie den Zwischentyp kennen müssen, um das Ergebnis von an op₁zu übergeben op₂. Das richtige System für den existenziellen Typ sollte den richtigen Typ auswählen, der durch die Bedingung garantiert existiert. Dh Sie sollten in der Lage sein, Funktion mit Typ zu schreiben : ∀X. X→(X→boolean)→T. Im vorherigen Beispiel wird eine solche Funktion als XKonstruktor verwendet X 3 show( showist eine Funktion, die Argumente eines beliebigen Typs akzeptiert, der implementiert Showund zurückgibt String).

Aktualisiert: Ich habe Ihre Frage gerade noch einmal gelesen und denke, ich habe die richtige Konstruktion für Java:

interface T {
    boolean op₂();
}
...
T x = new T() {
    private final int op = ...;
    public boolean op₂() { return ((op % 2) == 0); }
};
T y = new T() {
    private final char op = ...;
    public boolean op₂() { return ('0' <= op && op <= '9'); }
};
if (x.op₂() && y.op₂()) ...

Sie haben Recht mit der Erwähnung this- es ist eigentlich Ihre Meinung.

Ich glaube, ich habe jetzt verstanden, dass klassische OOP-Sprachen (Java, C #, C ++ usw.) immer einen existenziellen Typ mit einem einzelnen Wert thisund einer Funktion darüber implementieren , die "Methoden" genannt wird und implizit mit diesem Wert aufgerufen wird :)

PS Entschuldigung, ich bin mit Java nicht sehr vertraut, aber ich hoffe, Sie haben die Idee.

nur
quelle
Ich füge hinzu, dass Sie sich den SAM-Typ (Single Abstract Method) ansehen möchten, der in Java 8 zur Unterstützung der funktionalen Programmierung eingeführt wird.
Martijn Verburg
2

Der einzige Unterschied besteht darin, dass die Java-Schnittstelle dem Java-Compiler tatsächlich etwas bedeutet.

Der existenzielle Typ ist die formale Definition eines Typs, der für keine Sprache spezifisch ist. Informatiker verwenden diese Art der Definition, um Dinge über den Typ und über die Sprachen, die ihn implementieren, zu beweisen. Die Java-Schnittstelle ist eine der Java-Implementierungen des formal definierten Typs.

Matthew Flynn
quelle
Nee. Siehe William Kochpapier.
Nicole
2

Die 2 vorgestellten Typen unterscheiden sich stark voneinander. Die von Ihnen geschriebene Schnittstellendefinition ist ein universeller Typ (Java-Generika fallen im Allgemeinen in diese Kategorie).

Ein existenzieller Typ verbirgt einen Typ innerhalb seiner Implementierung vor dem Verbraucher. Damit X in T existenziell ist, kann die Identität von X intuitiv keinem Verbraucher bekannt sein. Alles, was bekannt sein sollte, ist die Menge der Operationen, die bei der Definition bereitgestellt werden. Es gibt einen Typ T für einen Typ X.

Im Gegensatz dazu definiert ein universeller Typ Operationen, die für alle Typen gelten und aus denen der Verbraucher frei wählen kann. Der Schnittstellentyp T ist genau das. X wird vom Verbraucher instanziiert, der genau weiß, um welchen Typ X es sich handelt. Für jeden Typ X im Universum gibt es einen Typ T.

Existentials sind in Java als Sprachkonstrukt nicht vorhanden, außer im begrenzten Fall von Platzhaltern ( List<?>). Aber ja, sie können mit Schnittstellen emuliert werden. Das Problem wird dann mehr vom Design.

Wie nur erwähnt, ist es in einer objektorientierten Umgebung schwierig, Existentials zu implementieren, da die Art und Weise, wie Sie normalerweise die Typinformationen von X codieren (was Sie damit tun können), darin besteht, Elementfunktionen in einem Schnittstellentyp zu haben, den X implementiert. Kurz gesagt, Schnittstellen können einige Typabstraktionsfunktionen erwerben, erfordern jedoch in gewissem Maße die Beseitigung des Existenziellen.

Rafael
quelle