Каков наилучший способ преобразования String в ByteString в Haskell?
Моя реакция на проблему -
import qualified Data.ByteString as B
import Data.Char (ord)
packStr = B.pack . map (fromIntegral . ord)
Но это не кажется удовлетворительным.
Каков наилучший способ преобразования String в ByteString в Haskell?
Моя реакция на проблему -
import qualified Data.ByteString as B
import Data.Char (ord)
packStr = B.pack . map (fromIntegral . ord)
Но это не кажется удовлетворительным.
Data.ByteString [.Lazy].Char8.pack
Вы можете обычно использовать hoogle для поиска функций.
Data.ByteString.UTF8.fromString также полезна. Версия Char8 потеряет unicode-ness, а UTF8 сделает кодировку ByteString с кодировкой UTF8. Вы должны выбрать тот или другой.
Безопасный подход предполагает кодирование строки юникода:
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.
Вот мой чит-лист для строкового/ленивого преобразования 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
Пожалуйста, пишите, пишите, потому что он правильно занимается кодированием.