web-dev-qa-db-ja.com

文字列をByteStringに変換する最良の方法は何ですか

Haskellで文字列をByteStringに変換する最良の方法は何ですか?

問題に対する私の腸の反応は

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

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

しかし、これは満足のいくものではないようです。

32
Thomas Eding

これは、必要なエンコーディングがUTF-8であると仮定した場合の、Haskell String/Text/ByteString strict/lazy変換に関するチートシートです。 Data.Text.Encodingライブラリには、他のエンコーディングも利用できます。

必ずnot write(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 -- 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してください。

15
thetrutz

Data.ByteString.UTF8.fromStringも役立ちます。 Char8バージョンはUnicode性を失い、UTF8はUTF8でエンコードされたByteStringを作成します。どちらかを選択する必要があります。

26
Peaker

安全なアプローチには、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プラットフォームに付属しています。

11
robx