0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Haskell] ShortByteString の作り方 まとめ

Posted at

Strict ByteString および Lazy ByteString については別記事にしました。

参考「[Haskell] Strict ByteString の作り方 まとめ - Qiita
参考「[Haskell] Lazy ByteString の作り方 まとめ - Qiita

各関数の説明等は公式ドキュメント等を参照。

参考「Data.ByteString.Builder
参考「Data.ByteString.Short

ShortByteString は直接 putStrputStrLn することはできません。
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 と異なり、ShortByteStringString = [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"

ShortByteStringfromStringString 型の文字列を UTF-8 として扱いませんが、BuilderfromStringString 型の文字列を 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"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?