Ich lerne gerade über existenzielle Quantifizierung, Phantomtypen und GADTs. Wie gehe ich vor, um eine heterogene Liste eines Datentyps mit einer Phantomvariablen zu erstellen? Zum Beispiel:
%Vor%Funktionen wie unten sind OK:
%Vor%Ich würde jedoch gerne eine heterogene Liste wie folgt deklarieren können:
%Vor% Ich habe versucht, eine leere Typklasse zu verwenden, um den Typ in a
von:
Aber das obige würde nicht kompilieren. Ich konnte mithilfe der existenziellen Quantifizierung Folgendes erreichen:
%Vor% Aber auf diese Weise kann ich keine Funktion anwenden, die auf dem spezifischen Typ von a
in Toy a
bis T
z. addOne
oben.
Zusammenfassend, wie kann ich eine heterogene Liste erstellen, ohne die Phantom-Variable zu vergessen / zu verlieren?
Beginnen Sie mit dem Toy
-Typ:
Nun können Sie es in ein existentielles ohne mit dem Klassensystem übergeneralisieren:
%Vor% Da der Wrapper nur Toy
s enthält, können wir sie auspacken und erhalten Toy
s zurück:
Und jetzt können Sie Dinge innerhalb der Liste unterscheiden:
%Vor%Wie Cirdec hervorhebt, können die verschiedenen Stücke ein wenig auseinandergenommen werden:
%Vor% Ich sollte auch beachten, dass hier bisher nichts das Toy
GADT rechtfertigt. Bheklilrs einfacherer Ansatz, einen einfachen algebraischen Datentyp zu verwenden, sollte gut funktionieren.
Vor ein paar Tagen gab es eine sehr ähnliche Frage / p>
In Ihrem Fall wäre es
%Vor%Es ist leicht, eine Existenz zu beseitigen:
%Vor% Wenn Sie einen Recursor für den Toy
-Datentyp
Sie können eine umschlossene toy
:
Zum Beispiel
%Vor%Dieser Ansatz ähnelt dem in @ dfeuer's Antwort, aber es ist weniger ad hoc.
Hast du mit Data.Typeable
gespielt? Eine Typeable
-Einschränkung ermöglicht es Ihnen, Vermutungen an dem Typ durchzuführen, der durch das Existential verborgen ist, und auf diesen Typ zu werfen, wenn Sie richtig raten.
Nicht dein Beispiel, sondern ein Beispielcode, den ich herumliegen habe:
%Vor%Tags und Links haskell existential-type gadt phantom-types