2010-07-12 4 views
20

Каков наилучший способ преобразования String в ByteString в Haskell?Каков наилучший способ преобразования String в ByteString

Моя инстинктивная реакция на проблемы

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

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

Но это не кажется удовлетворительным.

+4

Modern: Обычно вы должны преобразовывать '[Char]' в 'Text' и' [Word8] 'в' ByteString'. Его все еще 'pack' хотя :) – alternative

+2

Преобразование Unicode в байты включает использование кодировки Unicode. Использование 'pack' больше похоже на небезопасный листинг. – tibbe

ответ

24

Data.ByteString[.Lazy].Char8.pack

Вы можете использовать, как правило, hoogle найти функции.

+0

Это хороший способ использовать hoogle! – eccstartup

+0

Это работает для Char8 ByteStrings, но что вы можете использовать для ByteStrings в Word8? –

+1

@fractal Они точно такие же, поэтому он работает для обоих. –

14

Data.ByteString.UTF8.fromString также полезен. Версия Char8 потеряет unicode-ness, а UTF8 сделает кодировку ByteString с кодировкой UTF8. Вы должны выбрать тот или другой.

+0

В случае возникновения вопроса: эта функция не находится в Hoogle, поскольку она индексирует только небольшой набор библиотек (поставляемых с GHC). Расширение набора библиотек, индексированных Hoogle, появилось несколько раз, но не было сделано. Я думаю, из-за ограничений времени разработчика Google (Neil). FYI, обсуждаемая здесь функция - из пакета utf8-string. –

+0

@TomMD: Hayoo обращается к этому: http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:String%20-%3E%20ByteString – Peaker

+0

@peaker: Не для меня. Айоу плохо справляется с поиском типа, особенно когда тип является общим или полиморфным. –

5

Безопасный подход будет включать в себя кодирующий юникод строку:

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 

Что касается других ответов: Data.ByteString.Char8.pack фактически то же самое, что и версия в этом вопросе, и вряд ли будет что вы хотите:

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 это хорошо, но требует пакет utf8-строки, в то время как Data.Text.Encoding поставляется с Haskell Platform.

+1

'Codec.Binary.UTF8.String' также может использоваться –

4

Вот мой обманщик для строки Haskell String/Text/ByteString с строгим/ленивым преобразованием, предполагая, что желаемой кодировкой является UTF-8. Библиотека Data.Text.Encoding имеет другие кодировки.

Пожалуйста, убедитесь, что не записи (с использованием OverloadedStrings):

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

Это будет получить закодированную неожиданным образом. Попробуйте

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

вместо этого.

Строковые литералы типа «Текст» отлично работают с кодировкой.

Шпаргалка:

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 

Пожалуйста +1 ответа акустического, потому что он правильно занимается кодированием.

Смежные вопросы