2011-01-15 13 views
10

Ich bin neu in Haskell und ich versuche, eine reine SHA1-Implementierung in meiner App (Data.Digest.Pure.SHA) mit einer JSON-Bibliothek (AttoJSON) zu verwenden.Der beste Weg, um zwischen [Char] und [Word8] zu konvertieren?

AttoJSON verwendet Data.ByteString.Char8 bytestrings, SHA Data.ByteString.Lazy bytestrings verwendet, und einige meiner Stringliterale in meiner app sind [Char].

Haskell Prime's wiki page on Char types scheint darauf hinzuweisen, dass etwas noch in der Haskell-Sprache/Prelude ausgearbeitet wird.

Und this blogpost on unicode support listet ein paar Bibliotheken, aber es ist ein paar Jahre alt.

Was ist der beste Weg, um zwischen diesen Typen zu konvertieren, und was sind die Kompromisse?

Danke!

+0

http: //hackage.haskell.org/packages/archive/utf8-string/0.3.7/doc/html/Data-ByteString-Lazy-UTF8.html – singpolyma

+0

Beachten Sie, dass ein 'Char' * nicht sicher in' Word8' konvertiert werden kann weil 'Char' speichern kann viel mehr Werte als 'Word8'. – singpolyma

Antwort

2

Char8 und normale Bytestrings sind das gleiche, nur mit verschiedenen Schnittstellen, je nachdem, welches Modul Sie importieren. Hauptsächlich möchten Sie zwischen strikten und faulen Bytestrings konvertieren, für die Sie toChunks und fromChunks verwenden.

Um Zeichen in Bytestrings zu setzen, verwenden Sie pack.

Beachten Sie auch, dass, wenn Ihre Zeichen Codepoints enthalten, die Multibyte-Darstellungen in UTF-8, dann wird es Probleme geben.

4

Für die Konvertierung zwischen Char8 und Word8 sollten Sie toEnum/fromEnum Konvertierungen verwenden können, da sie die gleichen Daten darstellen.

Für Char und Strings könnten Sie mit Data.ByteString.Char8.pack/unpack oder einer Kombination aus map, toEnum und fromEnum davonkommen, aber das wirft Daten raus, wenn Sie etwas anderes als verwenden ASCII.

Für Strings, die mehr als nur ASCII enthalten können, ist die UTF8-Codierung eine beliebte Wahl. Ich mag die UTF-8-String-Paket für diese:

http://hackage.haskell.org/packages/archive/utf8-string/0.3.6/doc/html/Codec-Binary-UTF8-String.html

0

Vielleicht möchten Sie, dies zu tun:

import Data.ByteString.Internal (unpackBytes) 
import Data.ByteString.Char8 (pack) 
import GHC.Word (Word8) 

strToWord8s :: String -> [Word8] 
strToWord8s = unpackBytes . pack 
3

Hier ist, was ich habe, ohne ByteString internen Funktionen.

import Data.ByteString as S (ByteString, unpack) 
import Data.ByteString.Char8 as C8 (pack) 
import Data.Char (chr) 

strToBS :: String -> S.ByteString 
strToBS = C8.pack 

bsToStr :: S.ByteString -> String 
bsToStr = map (chr . fromEnum) . S.unpack 

S.unpack auf einem ByteString gibt uns [Word8], wir (chr . fromEnum) gelten, die jede Enum-Typ auf ein Zeichen umwandelt. Indem wir alle zusammen komponieren, werden wir die Funktion haben, die wir wollen!

1

Hinweis: Dies beantwortet die Frage in einem sehr speziellen Fall (Aufruf von Funktionen auf fest codierten Strings).

Dies scheint ein kleines Problem zu sein, da Konvertierungsfunktionen wie in vorherigen Antworten beschrieben existieren. Aber ich wollte eine Methode, um Verwaltungscode zu reduzieren, d. H. Den Code, den Sie schreiben müssen, nur um Funktionen zusammenzuarbeiten.

Die Lösung Typ-Handling-Code für Strings zu reduzieren, ist die OverloadedStrings Pragma und importieren Sie das entsprechende Modul (e)

{-# LANGUAGE OverloadedStrings #-} 
module Dummy where 
import Data.ByteString.Lazy.Char8 (ByteString, append) 

bslHandling :: ByteString -> ByteString 
bslHandling = (append myWord8List) 

myWord8List = "I look like a String, but I'm actually a ByteString" 

Hinweis zu verwenden: Typ vom Compiler wird gefolgert myWordList.

  • Wenn Sie nicht es in bslHandling verwenden, dann ist die obige Erklärung wird yeld ein klassischer [Char] Typ.

  • Es löst nicht das Problem von einem bestimmten Typ in einem anderen

Hoffe, es hilft Unter der Annahme,

0

zugeben, dass Char und Word8 gleich ist,

import Data.Word (Word8) 
import Unsafe.Coerce (unsafeCoerce) 

toWord8 :: Char -> Word8 
toWord8 = unsafeCoerce 

strToWord8 :: String -> Word8 
strToWord8 = map toWord8 
+0

Das ist eine sehr schlechte Annahme, da Haskell Unicode unterstützt. unsafeCoerce wird genau wegen solcher Dinge als unsicher bezeichnet. – Evi1M4chine

+0

In der Tat ist Jacob Wangs Antwort viel besser. – penkovsky

Verwandte Themen