Schönen Tag.
Das einzige, was ich jetzt an Haskell hasse, ist die Menge an Paketen für die Arbeit mit Strings.
Zuerst habe ich native Haskell- [Char]
Strings verwendet, aber als ich versuchte, Hackage-Bibliotheken zu verwenden , ging ich in endlosen Konvertierungen völlig verloren. Jedes Paket scheint eine andere Zeichenfolgenimplementierung zu verwenden, einige übernehmen ihre eigene handgemachte Sache.
Als nächstes habe ich meinen Code mit Data.Text
Zeichenfolgen und OverloadedStrings
Erweiterungen umgeschrieben. Ich habe mich dafür entschieden, Text
weil er einen größeren Funktionsumfang hat, aber es scheint, dass viele Projekte dies bevorzugen ByteString
.
Jemand könnte kurz überlegen, warum man das eine oder andere benutzt?
PS: Übrigens, wie konvertiert man von Text
nach ByteString
?
Konnte nicht erwartet Typ entsprechen Data.ByteString.Lazy.Internal.ByteString gegen gefolgert Typ Text IO Data.ByteString.Lazy.Internal.ByteString Inferred Typ: IO Text Erwartete Typ
Ich habe versucht , encodeUtf8
aus Data.Text.Encoding
, aber kein Glück:
Der erwartete Typ Data.ByteString.Lazy.Internal.ByteString konnte nicht mit dem abgeleiteten Typ Data.ByteString.Internal.ByteString verglichen werden
UPD:
Vielen Dank für die Antworten, dass * Chunks Güte wie ein langer Weg aussieht, aber ich war etwas schockiert über das Ergebnis, meine ursprüngliche Funktion sah folgendermaßen aus:
htmlToItems :: Text -> [Item]
htmlToItems =
getItems . parseTags . convertFuzzy Discard "CP1251" "UTF8"
Und jetzt wurde:
htmlToItems :: Text -> [Item]
htmlToItems =
getItems . parseTags . fromLazyBS . convertFuzzy Discard "CP1251" "UTF8" . toLazyBS
where
toLazyBS t = fromChunks [encodeUtf8 t]
fromLazyBS t = decodeUtf8 $ intercalate "" $ toChunks t
Und ja, diese Funktion funktioniert nicht, weil sie falsch ist. Wenn wir sie bereitstellen Text
, sind wir zuversichtlich, dass dieser Text ordnungsgemäß codiert und einsatzbereit ist. Die Konvertierung ist dumm, aber eine solch ausführliche Konvertierung muss noch durchgeführt werden irgendwo draußen platzieren htmltoItems
.
Text
wird zur De-facto- Textimplementierung . String gibt es aus alten Gründen und aus einfachen Gründen immer noch, aber für ernsthafte Textmanipulationen sollten Sie Text verwenden.Text
, und all diese Konvertierungen von Hand durchzuführen, fühlt sich nicht vernünftig an.htmlToItems = getItems . parseTags
Antworten:
ByteStrings
sind hauptsächlich für Binärdaten nützlich, bieten aber auch eine effiziente Möglichkeit, Text zu verarbeiten, wenn Sie lediglich den ASCII-Zeichensatz benötigen. Wenn Sie Unicode-Zeichenfolgen verarbeiten müssen, müssen Sie verwendenText
. Ich muss jedoch betonen, dass keines der beiden ein Ersatz für das andere ist und im Allgemeinen für verschiedene Zwecke verwendet wird: Während es sichText
um reinen Unicode handelt, müssen Sie immer noch zu und von einer binärenByteString
Darstellung codieren, wenn Sie z. B. Text über einen Socket oder eine Datei transportieren .Hier ist ein guter Artikel über die Grundlagen von Unicode, der die Beziehung zwischen Unicode-Codepunkten (
Text
) und den codierten Binärbytes (ByteString
) anständig erklärt : Das absolute Minimum, das jeder Softwareentwickler unbedingt und positiv über Unicode und Zeichen wissen muss SetsSie können das Data.Text.Encoding- Modul verwenden, um zwischen den beiden Datentypen zu konvertieren, oder Data.Text.Lazy.Encoding, wenn Sie die Lazy-Varianten verwenden (wie Sie es anscheinend aufgrund Ihrer Fehlermeldungen tun).
quelle
Text against inferred type Data.Text.Lazy.Internal.Text
Also fand ich fromChunks for Text, ok, aber das Endergebnis noch hässlich.text
Paket bietet tatsächlich Funktionen, um bereits mit Dateien zu arbeiten.Data.Text.IO
Modul verfügt über Funktionen zum Arbeiten mit Dateien, die jedoch fast nie Ihren Wünschen entsprechen. Sie werden internText
von derByteString
Verwendung des Standardzeichensatzes Ihres Systemgebietsschemas dekodiert . Wenn die Datei zufällig eine andere Codierung aufweist, führt dies zu einem Laufzeitfehler oder einem Mülltext. Das explizite Codieren und Decodieren ist fast immer die richtige Option.Sie möchten auf jeden Fall Data.Text für Textdaten verwenden.
encodeUtf8
ist der Weg zu gehen. Dieser Fehler:bedeutet, dass Sie dem Code einen strengen Bytestring bereitstellen, der einen faulen Bytestring erwartet . Die Konvertierung ist mit der
fromChunks
Funktion einfach :Data.ByteString.Lazy.fromChunks :: [Data.ByteString.Internal.ByteString] -> ByteString
Alles, was Sie tun müssen, ist, die Funktion
fromChunks [myStrictByteString]
dort hinzuzufügen, wo der faule Bytestring erwartet wird.Die Konvertierung in die andere Richtung kann mit der Doppelfunktion durchgeführt werden
toChunks
, die einen verzögerten Testtest durchführt und eine Liste strenger Blöcke enthält.Möglicherweise möchten Sie die Betreuer einiger Pakete fragen, ob sie eine Textschnittstelle anstelle oder zusätzlich zu einer Bytestring-Schnittstelle bereitstellen können.
quelle
Verwenden Sie eine einzelne Funktion
cs
aus demData.String.Conversions
.Es ermöglicht Ihnen , zwischen zu konvertieren
String
,ByteString
undText
(wie auchByteString.Lazy
undText.Lazy
), in Abhängigkeit von der Eingabe und der erwarteten Typen.Sie müssen es immer noch anrufen, müssen sich aber nicht mehr um die jeweiligen Typen kümmern.
In dieser Antwort finden Sie ein Verwendungsbeispiel.
quelle