Ich habe Verweise auf Haskell's gefunden Data.Typeable
, aber mir ist nicht klar, warum ich es in meinem Code verwenden möchte.
Welches Problem löst es und wie?
Antworten:
Data.Typeable
ist eine Kodierung eines bekannten Ansatzes (siehe z. B. Harper) zur Implementierung einer verzögerten (dynamischen) Typprüfung in einer statisch typisierten Sprache - unter Verwendung eines universellen Typs.
Ein solcher Typ umschließt Code, für den die Typprüfung erst in einer späteren Phase erfolgreich sein würde. Anstatt das Programm als falsch geschrieben abzulehnen, gibt der Compiler es zur Laufzeitprüfung weiter.
Der Stil stammt von Abadi et al. Und wurde von Cheney und Hinze für Haskell als Wrapper entwickelt, um alle dynamischen Typen darzustellen, wobei die Typeable
Klasse als Teil der SYB-Arbeit von SPJ und Lammel erscheint.
Referenz
Auch in den Lehrbüchern: Dynamische Typen (mit typisierbaren Darstellungen) sind statisch typisierte Sprachen mit nur einem Typ, Harper ch 20:
20.4 Untyped bedeutet Uni-Typed
Der untypisierte λ-Kalkül kann getreu in eine typisierte Sprache mit rekursiven Typen eingebettet sein. Dies bedeutet, dass jeder untypisierte λ-Term eine Darstellung als typisierten Ausdruck hat, so dass die Ausführung der Darstellung eines λ-Terms der Ausführung des Terms selbst entspricht. Bei dieser Einbettung geht es nicht darum, einen Interpreter für den λ-Kalkül in ℒ {+ × ⇀µ} zu schreiben (was wir sicherlich tun könnten), sondern um eine direkte Darstellung untypisierter λ-Terme als typisierte Ausdrücke in einer Sprache mit rekursiven Typen .
Die wichtigste Beobachtung ist, dass der untypisierte λ-Kalkül wirklich der uni-typisierte λ-Kalkül ist! Es ist nicht das Fehlen von Typen, das ihm seine Kraft verleiht, sondern dass es nur einen Typ hat, nämlich den rekursiven Typ
D = µt.t → t.
Es ist eine Bibliothek, in der unter anderem Typen benannt werden können. Wenn ein Typ a
deklariert ist Typeable
, dann kann man seinen Namen erhält mit show $ typeOf x
dem x
jedem Wert vom Typ ist a
. Es verfügt auch über begrenzte Typguss .
(Dies ähnelt in gewisser Weise der RTTI- oder dynamischen Sprachreflexion von C ++.)
Typeable
erlaubt kein Casting, das ist in Dynamic
. Und Dynamic
erlaubt kein Gießen zwischen verschiedenen Typen, da es eine sichere Hülle bildet unsafeCoerce
. Typeable
passt als Teil der Dynamic
sicheren Verpackung. Es bietet die Möglichkeit, eine Laufzeitdarstellung eines Typs abzurufen. Nichts mehr.
cast :: (Typeable a, Typeable b) => a -> Maybe b
- alles was du brauchst ist Typeable
, nicht Dynamic
involviert! Verwenden Sie Typeable
und cast
Sie können in der Tat Ihre eigenen Dynamic
ziemlich leicht rollen ...
dynApply
und dynApp
kann noch nicht mit der Typeable
Maschine ohne gemacht werden unsafeCoerce
. Das soll jedoch bald geschehen. Richard Eisenberg, Stephanie Weirich und einige andere Leuchten haben daran gearbeitet.
Eine der frühesten Beschreibungen einer Data.Typeable
ähnlichen Bibliothek für Haskell stammt von John Peterson aus dem Jahr 1992: http://www.cs.yale.edu/publications/techreports/tr1022.pdf
Das früheste "offizielle" Papier, das ich über die Einführung der eigentlichen Data.Typeable
Bibliothek kenne, ist das erste Scrap Your Boilerplate-Papier aus dem Jahr 2003: http://research.microsoft.com/en-us/um/people/simonpj/Papers/hmap/index.htm
Ich bin mir sicher, dass es eine Menge intervenierender Geschichte gibt, mit der sich jemand hier einlassen kann!
Die Data.Typeable- Klasse wird hauptsächlich für die generische Programmierung im SYB-Stil ( Scrap Your Boilerplate ) verwendet. Siehe auch Data.Data
Die Idee ist, dass SYB einen Sammlungskombinator definiert, um Vorgänge wie Drucken, Zählen, Suchen, Ersetzen usw. auf einheitliche Weise über eine Vielzahl von vom Benutzer erstellten Typen auszuführen. Die Typeable
Typklasse liefert die notwendigen Sanitärinstallationen.
In der modernen GHC können Sie nur sagen, deriving Data.Typeable
wenn Sie Ihren eigenen Typ definieren, um ihm die erforderlichen Instanzen bereitzustellen.