Strict ByteString
および Lazy ByteString
については別記事にしました。
参考「[Haskell] Strict ByteString の作り方 まとめ - Qiita」
参考「[Haskell] Lazy ByteString の作り方 まとめ - Qiita」
各関数の説明等は公式ドキュメント等を参照。
参考「Data.ByteString.Builder」
参考「Data.ByteString.Short」
※ ShortByteString
は直接 putStr
や putStrLn
することはできません。
※ Builder
から直接作れる ByteString
は Lazy ByteString
のみです。
※ Lazy ByteString
から直接 ShortByteString
を作ることはできません。
1. [Word8]
または Word8
から作る場合
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
let shortByteStringA = BSS.pack [99, 97, 116, 32, 227, 129, 173, 227, 129, 147]
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = BSS.singleton 99
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
let shortByteStringC = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.word8 $ 99
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
cat ねこ
"cat \227\129\173\227\129\147"
c
"c"
c
"c"
2. String = [Char]
または Char
から作る場合
2.1. 言語拡張を使わない場合
2.1.1. ASCII の場合
Strict ByteString
や Lazy ByteString
と異なり、ShortByteString
で String = [Char]
用の pack
関数は提供されていないため、 fromIntegral . ord
を用いて Char
から Word8
に変換します。
import Data.Char (ord)
import Data.String (fromString)
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
let shortByteStringA = BSS.pack . map (fromIntegral . ord) $ "cat"
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = fromString "cat"
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
let shortByteStringC = BSS.singleton . fromIntegral . ord $ 'c'
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
let shortByteStringD = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.string7 $ "cat"
BSC.putStrLn . BSS.fromShort $ shortByteStringD
print shortByteStringD
let shortByteStringE = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.char7 $ 'c'
BSC.putStrLn . BSS.fromShort $ shortByteStringE
print shortByteStringE
cat
"cat"
cat
"cat"
c
"c"
cat
"cat"
c
"c"
2.1.2. UTF-8 の場合
やり方によっては UTF-8 を正しく扱えないため注意が必要です。
import Data.Char (ord)
import Data.String (fromString)
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
-- UTF-8 を正しく扱えない
let shortByteStringA = BSS.pack . map (fromIntegral . ord) $ "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = fromString "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
let shortByteStringC = BSS.singleton . fromIntegral . ord $ 'ね'
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
-- UTF-8 を正しく扱える
let shortByteStringD = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.stringUtf8 $ "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringD
print shortByteStringD
let shortByteStringE = BSS.pack . BSL.unpack . BSB.toLazyByteString . fromString $ "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringE
print shortByteStringE
let shortByteStringF = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.charUtf8 $ 'ね'
BSC.putStrLn . BSS.fromShort $ shortByteStringF
print shortByteStringF
cat mS
"cat mS"
cat mS
"cat mS"
m
"m"
cat ねこ
"cat \227\129\173\227\129\147"
cat ねこ
"cat \227\129\173\227\129\147"
ね
"\227\129\173"
※ ShortByteString
の fromString
は String
型の文字列を UTF-8 として扱いませんが、Builder
の fromString
は String
型の文字列を UTF-8 として扱います。
2.2. OverloadedStrings
言語拡張を使う場合
2.2.1. ASCII の場合
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
let shortByteString = "cat"
BSC.putStrLn . BSS.fromShort $ shortByteString
print shortByteString
cat
"cat"
2.2.2. UTF-8 の場合
やり方によっては UTF-8 を正しく扱えないため注意が必要です。
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
-- UTF-8 を正しく扱えない
let shortByteStringA = "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
-- UTF-8 を正しく扱える
let shortByteStringB = BSS.pack . BSL.unpack . BSB.toLazyByteString $ "cat ねこ"
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
cat mS
"cat mS"
cat ねこ
"cat \227\129\173\227\129\147"
※ ShortByteString
の場合は String
型の文字列を UTF-8 として扱いませんが、Builder
の場合は String
型の文字列を UTF-8 として扱います。
3. Strict ByteString
または Lazy ByteString
から作る場合
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
--
let byteString = BS.pack [99, 97, 116, 32, 227, 129, 173, 227, 129, 147]
let shortByteStringA = BSS.toShort byteString
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.byteString $ byteString
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
--
let lazyByteString = BSL.pack [99, 97, 116, 32, 227, 129, 173, 227, 129, 147]
let shortByteStringC = BSS.pack . BSL.unpack $ lazyByteString
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
let shortByteStringD = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.lazyByteString $ lazyByteString
BSC.putStrLn . BSS.fromShort $ shortByteStringD
print shortByteStringD
cat ねこ
"cat \227\129\173\227\129\147"
cat ねこ
"cat \227\129\173\227\129\147"
cat ねこ
"cat \227\129\173\227\129\147"
cat ねこ
"cat \227\129\173\227\129\147"
参考「unpack - Data.ByteString.Lazy」
4. 空文字列の場合
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
let shortByteStringA = BSS.empty
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = mempty
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
let shortByteStringC = BSS.pack . BSL.unpack . BSB.toLazyByteString $ mempty
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
""
""
""
5. その他の型から作る場合
他にも様々な型の値から ShortByteString
を作ることができます。
ここでは例として一部のみ載せます。他の作り方に関しては公式ドキュメント等を参照して下さい。
参考「Data.ByteString.Builder」
参考「Data.ByteString.Short」
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Short as BSS
main :: IO ()
main = do
let shortByteStringA = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.word32BE $ 0x63617420
BSC.putStrLn . BSS.fromShort $ shortByteStringA
print shortByteStringA
let shortByteStringB = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.shortByteString $ shortByteStringA
BSC.putStrLn . BSS.fromShort $ shortByteStringB
print shortByteStringB
let shortByteStringC = BSS.pack . BSL.unpack . BSB.toLazyByteString . BSB.word32HexFixed $ 0x63617420
BSC.putStrLn . BSS.fromShort $ shortByteStringC
print shortByteStringC
cat
"cat "
63617420
"63617420"
63617420
"63617420"