2010-07-12 22 views
20

¿Cuál es la mejor manera de convertir una Cadena en ByteString en Haskell?¿Cuál es la mejor manera de convertir Cadena a ByteString

Mi reacción visceral al problema es

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

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

Pero esto no parece satisfactoria.

+4

Moderno: Normalmente debe convertir '[Char]' a 'Text' y' [Word8] 'a' ByteString'. Sin embargo, su 'paquete' :) – alternative

+2

La conversión de Unicode a bytes implica el uso de una codificación Unicode. Usar 'pack' es más similar a un lanzamiento inseguro. – tibbe

Respuesta

24

Data.ByteString[.Lazy].Char8.pack

normalmente puede utilizar para encontrar hoogle funciones.

+0

¡Es una buena manera de usar hoogle! – eccstartup

+0

Esto funciona para Char8 ByteStrings, pero ¿qué se puede usar para ByteStrings of Word8? –

+1

@fractal Son del mismo tipo, por lo que funciona para ambos. –

14

Data.ByteString.UTF8.fromString también es útil. La versión Char8 perderá el carácter unicode-ness y UTF8 hará una ByteString codificada en UTF8. Tienes que elegir uno u otro.

+0

En caso de que surja la pregunta: esta función no está ubicada por Hoogle porque solo indexa un pequeño conjunto de bibliotecas (las enviadas con GHC). Expandir el conjunto de bibliotecas indexadas por Hoogle ha aparecido varias veces, pero no se ha hecho, creo que debido a las limitaciones de tiempo del desarrollador de Hoogle (Neil). FYI, la función que se trata aquí es del paquete utf8-string. –

+0

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

+0

@peaker: No es para mi satisfacción. Hayoo hace un mal trabajo en la búsqueda de tipos, particularmente cuando el tipo es general o polimórfico. –

5

Un enfoque seguro implicará que codifica la cadena 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 

En cuanto a las otras respuestas: Data.ByteString.Char8.pack es efectivamente el mismo que la versión de la pregunta, y es poco probable que sea lo que desee:

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 está muy bien, pero requiere el paquete utf8-cadena, mientras que Data.Text.Encoding viene con la Plataforma Haskell.

+1

'Codec.Binary.UTF8.String' también se puede usar –

4

Aquí está mi hoja de trucos para Haskell String/Text/ByteString strict/perezosa conversión suponiendo que la codificación deseada es UTF-8. La biblioteca Data.Text.Encoding tiene otras codificaciones disponibles.

Por favor asegúrese de que no escritura (usando OverloadedStrings):

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

Esto hará que codificado de una manera inesperada. Pruebe

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

en su lugar.

Los literales de cadena del tipo 'Texto' funcionan bien con respecto a la codificación.

hoja de trucos:

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 

favor, 1 respuesta de Peaker, porque él correctamente se ocupa de codificación.

Cuestiones relacionadas