Ich habe eine Liste von Tupeln des Formats [(String, String)] und ich brauche eine Funktion, um den Inhalt der Liste in eine Textdatei zu schreiben, dann eine andere Funktion, um diese Textdatei als dieselbe Liste von Tupeln zu lesen . Hier ist, was ich für die Speicherfunktion habe:
%Vor%Wäre das ein gutes Format für die Textdatei? Wie könnte ich dann diese Textdatei lesen und in die Liste der Tupel zurück konvertieren?
Definiert in Prelude
,
Kurz gesagt, dies sind die Standard-Serialisierungsmethoden in Haskell. show :: (Show a) => a -> String
kann alles, was eine Instanz von Show
ist, in eine Zeichenkette umwandeln, und read :: (Read a) => String -> a
kann eine Zeichenkette in alles umwandeln, das eine Instanz von Read
ist (oder eine Ausnahme auslöst).
Die meisten integrierten Typen und Datenstrukturen in der Standardbibliothek haben Show
und Read
Instanzen definiert; Wenn Sie Teile aus ihnen zusammensetzen, hat Ihr Typ auch Show
und Read
Instanzen definiert.
Wenn Table
ein Datentyp ist, müssen Sie nach den Instanzen fragen, aber Sie können verlangen, dass der Compiler sie automatisch für Sie ableitet.
Manchmal ist das nicht möglich und Sie müssen Ihre eigenen Instanzen definieren.
%Vor%Aber das sollte nicht üblich sein.
Der show
/ read
-Ansatz wird gut funktionieren, ich benutze ihn auch, aber nur für kleine Werte. Bei größeren, komplexeren Werten ist read
sehr langsam.
Dieses erfundene Beispiel zeigt die schlechte Leistung von read
:
Außerdem wird read
nicht in der Lage sein, einige gültige Haskell-Ausdrücke zu lesen, insbesondere solche, die Infix-Konstruktoren verwenden (wie die :<
in meinem Beispiel). Der Grund dafür ist, dass read
sich der Beharrlichkeit der Operatoren nicht bewusst ist. Das ist auch der Grund, warum show $ Nil :< 1 :< 2 :< 3
viele scheinbar überflüssige Klammern erzeugt.
Wenn Sie Serialisierung für größere Werte haben möchten, würde ich vorschlagen, eine andere Bibliothek wie Data.Binary zu verwenden. Dies wird etwas komplexer sein als ein einfacher show
, hauptsächlich wegen des Fehlens von deriving Binary
. Es gibt jedoch verschiedene generische Programmierlösungen, die Ihnen deriving
-ähnliche Surrogate geben.
Fazit: Ich würde sagen, benutze die show
/ read
-Lösung, bis du an ihre Grenzen stößt (wahrscheinlich sobald du anfängst, echte Anwendungen zu erstellen), dann beginne etwas Skalierbares ( aber auch komplexer) wie Data.Binary.
Randnotiz: Für diejenigen, die sich für Parser und fortgeschrittenere Haskell-Sachen interessieren; Die Beispiele, die ich gab, stammten aus der Zeitung: Haskel Do You Read Me? , alternativ, schnell read
-ähnliche Funktion.
Mit Ihrer aktuellen Funktion haben Sie ein Problem, wenn die Strings in der Liste "," oder ")" enthalten, da es unmöglich ist herauszufinden, wo eine Zeichenfolge endet, wenn Sie versuchen, die Daten erneut zu lesen. Sie müssten diese Zeichen auf irgendeine Weise entfliehen, wenn sie in einer Zeichenfolge angezeigt werden.
Es ist viel einfacher, show
und zu verwenden read
um Ihre Daten in Strings und dann zu konvertieren um es selbst zu tun:
show
entkommt Sonderzeichen und stellt sicher, dass die Daten in einem Format vorliegen, das von read
analysiert werden kann. Um die Daten zu laden, lesen Sie die Datei in eine Zeichenfolge und übergeben diese an read
, um sie in die gewünschte Datenstruktur zu konvertieren.