2010-07-12 1 views
20

Qual è il modo migliore per convertire una stringa in un ByteString in Haskell?Qual è il modo migliore per convertire String in ByteString

La mia reazione istintiva al problema è

import qualified Data.ByteString as B 
import Data.Char (ord) 

packStr = B.pack . map (fromIntegral . ord) 

Ma questo non sembra soddisfacente.

+4

Moderno: è necessario convertire in genere '[Char]' in 'Text' e' [Word8] 'in' ByteString'. È ancora 'pack' però :) – alternative

+2

Convertire Unicode in byte comporta l'uso di una codifica Unicode. L'uso di 'pack' è più simile a un cast non sicuro. – tibbe

risposta

24

Data.ByteString[.Lazy].Char8.pack

in genere è possibile utilizzare per trovare hoogle funzioni.

+0

È un bel modo di usare hoogle! – eccstartup

+0

Funziona con Char8 ByteStrings, ma cosa puoi usare per ByteStrings di Word8? –

+1

@fractal Sono esattamente lo stesso tipo, quindi funziona per entrambi. –

14

Data.ByteString.UTF8.fromString è anche utile. La versione Char8 perderà l'unicode-ness e UTF8 creerà un ByteString codificato in UTF8. Devi scegliere l'uno o l'altro.

+0

Nel caso in cui la domanda venga visualizzata: questa funzione non è localizzata da Hoogle perché indicizza solo una piccola serie di librerie (quelle fornite con GHC). L'espansione dell'insieme di librerie indicizzate da Hoogle è emersa diverse volte, ma non è stata eseguita, a causa dei limiti di tempo dello sviluppatore di Hoogle (Neil). FYI, la funzione discussa qui viene dal pacchetto utf8-string. –

+0

@TomMD: Hayoo affronta questo: http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:String%20-%3E%20ByteString – Peaker

+0

@peaker: non è per mia soddisfazione. Hayoo fa uno scarso lavoro alla ricerca dei tipi, in particolare quando il tipo è generale o polimorfico. –

5

Un approccio sicuro coinvolgerà la codifica la stringa unicode:

import qualified Data.ByteString as B 
import qualified Data.Text as T 
import Data.Text.Encoding (encodeUtf8) 

packStr'' :: String -> B.ByteString 
packStr'' = encodeUtf8 . T.pack 

Per quanto riguarda le altre risposte: Data.ByteString.Char8.pack è effettivamente la stessa della versione in questione, ed è improbabile che sia quello si vuole:

import qualified Data.ByteString as B 
import qualified Data.ByteString.Char8 as C 
import qualified Data.Text as T 
import Data.Text.Encoding (encodeUtf8) 
import Data.Char (ord) 

packStr, packStr', packStr'' :: String -> B.ByteString 
packStr = B.pack . map (fromIntegral . ord) 
packStr' = C.pack 
packStr'' = encodeUtf8 . T.pack 

*Main> packStr "hellö♥" 
"hell\246e" 
*Main> packStr' "hellö♥" 
"hell\246e" 
*Main> packStr'' "hellö♥" 
"hell\195\182\226\153\165" 

Data.ByteString.UTF8.fromString va bene, ma richiede il pacchetto utf8-string, mentre Data.Text.Encoding viene fornito con la piattaforma Haskell.

+1

'Codec.Binary.UTF8.String' può anche essere utilizzato –

4

Ecco il mio cheat sheet per Haskell String/Text/ByteString conversione rigorosa/lenta assumendo che la codifica desiderata sia UTF-8. La libreria Data.Text.Encoding ha altre codifiche disponibili.

Assicurati di non scrittura (utilizzando OverloadedStrings):

lazyByteString :: BL.ByteString 
lazyByteString = "lazyByteString ä ß" -- BAD! 

Questo otterrà codificato in modo inaspettato. Prova

lazyByteString = BLU.fromString "lazyByteString ä ß" -- good 

invece.

Le stringhe di tipo "Testo" funzionano bene per quanto riguarda la codifica.

Cheat Sheet:

import Data.ByteString.Lazy as BL 
import Data.ByteString as BS 
import Data.Text as TS 
import Data.Text.Lazy as TL 
import Data.ByteString.Lazy.UTF8 as BLU 
import Data.ByteString.UTF8 as BSU 
import Data.Text.Encoding as TSE 
import Data.Text.Lazy.Encoding as TLE 

-- String <-> ByteString 

BLU.toString :: BL.ByteString -> String 
BLU.fromString :: String -> BL.ByteString 
BSU.toString :: BS.ByteString -> String 
BSU.fromString :: String -> BS.ByteString 

-- String <-> Text 

TL.unpack :: TL.Text -> String 
TL.pack :: String -> TL.Text 
TS.unpack :: TS.Text -> String 
TS.pack :: String -> TS.Text 

-- ByteString <-> Text 

TLE.encodeUtf8 :: TL.Text -> BL.ByteString 
TLE.decodeUtf8 :: BL.ByteString -> TL.Text 
TSE.encodeUtf8 :: TS.Text -> BS.ByteString 
TSE.decodeUtf8 :: BS.ByteString -> TS.Text 

-- Lazy <-> Strict 

BL.fromStrict :: BS.ByteString -> BL.ByteString 
BL.toStrict :: BL.ByteString -> BS.ByteString 
TL.fromStrict :: TS.Text -> TL.Text 
TL.toStrict :: TL.Text -> TS.Text 

prega +1 risposta di Peaker, perché si occupa in modo corretto con la codifica.