41

在 Haskell 中将 String 转换为 ByteString 的最佳方法是什么?

我对这个问题的直觉反应是

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

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

但这似乎并不令人满意。

4

3 回答 3

45

这是我的 Haskell 字符串/文本/字节字符串严格/延迟转换的备忘单,假设所需的编码是 UTF-8。Data.Text.Encoding 库有其他可用的编码。

请确保不要写(使用 OverloadedStrings):

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

这将以意想不到的方式编码。尝试

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

反而。

'Text' 类型的字符串文字在编码方面工作得很好。

备忘单:

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 -- from utf8-string
import Data.ByteString.UTF8 as BSU      -- from utf8-string
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 Peaker 的回答,因为他正确处理编码。

于 2016-11-08T15:45:24.667 回答
28

Data.ByteString.UTF8.fromString也很有用。该Char8版本将失去 unicode-ness 并且 UTF8 将生成 UTF8-encoded ByteString。你必须选择其中之一。

于 2010-07-13T19:14:51.617 回答
16

一种安全的方法将涉及对 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

关于其他答案: 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-string 包,而 Data.Text.Encoding 是 Haskell 平台自带的。

于 2014-04-01T18:30:19.420 回答