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] Lazy ByteString の作り方 まとめ

Last updated at Posted at 2023-10-01

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

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

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

参考「Data.ByteString.Builder
参考「Data.ByteString.Lazy
参考「Data.ByteString.Lazy.Char8

1. [Word8] または Word8 から作る場合

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    let lazyByteStringA = BSL.pack [99, 97, 116, 32, 227, 129, 173, 227, 129, 147]
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = BSL.singleton 99
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    let lazyByteStringC = BSB.toLazyByteString . BSB.word8 $ 99
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC
実行結果
cat ねこ
"cat \227\129\173\227\129\147"
c
"c"
c
"c"

2. String = [Char] または Char から作る場合

2.1. 言語拡張を使わない場合

2.1.1. ASCII の場合

import Data.String (fromString)

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    let lazyByteStringA = BSLC.pack "cat"
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = fromString "cat"
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    let lazyByteStringC = BSLC.singleton 'c'
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC

    let lazyByteStringD = BSB.toLazyByteString . BSB.string7 $ "cat"
    BSLC.putStrLn lazyByteStringD
    print lazyByteStringD

    let lazyByteStringE = BSB.toLazyByteString . BSB.char7 $ 'c'
    BSLC.putStrLn lazyByteStringE
    print lazyByteStringE
実行結果
cat
"cat"
cat
"cat"
c
"c"
cat
"cat"
c
"c"

2.1.2. UTF-8 の場合

やり方によっては UTF-8 を正しく扱えないため注意が必要です。

import Data.String (fromString)

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    -- UTF-8 を正しく扱えない
    let lazyByteStringA = BSLC.pack "cat ねこ"
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = fromString "cat ねこ"
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    let lazyByteStringC = BSLC.singleton 'ね'
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC

    -- UTF-8 を正しく扱える
    let lazyByteStringD = BSB.toLazyByteString . BSB.stringUtf8 $ "cat ねこ"
    BSLC.putStrLn lazyByteStringD
    print lazyByteStringD

    let lazyByteStringE = BSB.toLazyByteString . fromString $ "cat ねこ"
    BSLC.putStrLn lazyByteStringE
    print lazyByteStringE

    let lazyByteStringF = BSB.toLazyByteString . BSB.charUtf8 $ 'ね'
    BSLC.putStrLn lazyByteStringF
    print lazyByteStringF
実行結果
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"

ByteStringfromStringString 型の文字列を UTF-8 として扱いませんが、BuilderfromStringString 型の文字列を UTF-8 として扱います。

2.2. OverloadedStrings 言語拡張を使う場合

2.2.1. ASCII の場合

{-# LANGUAGE OverloadedStrings #-}

import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    let lazyByteString = "cat"
    BSLC.putStrLn lazyByteString
    print lazyByteString
実行結果
cat
"cat"

2.2.2. UTF-8 の場合

やり方によっては UTF-8 を正しく扱えないため注意が必要です。

{-# LANGUAGE OverloadedStrings #-}

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    -- UTF-8 を正しく扱えない
    let lazyByteStringA = "cat ねこ"
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    -- UTF-8 を正しく扱える
    let lazyByteStringB = BSB.toLazyByteString "cat ねこ"
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB
実行結果
cat mS
"cat mS"
cat ねこ
"cat \227\129\173\227\129\147"

ByteString の場合は String 型の文字列を UTF-8 として扱いませんが、Builder の場合は String 型の文字列を UTF-8 として扱います。

3. Strict ByteString または ShortByteString から作る場合

import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Lazy.Char8 as BSLC
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 lazyByteStringA = BSLC.fromStrict byteString
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = BSB.toLazyByteString . BSB.byteString $ byteString
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    -- 
    let shortByteString = BSS.pack [99, 97, 116, 32, 227, 129, 173, 227, 129, 147]

    let lazyByteStringC = BSL.pack . BSS.unpack $ shortByteString
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC

    let lazyByteStringD = BSB.toLazyByteString . BSB.shortByteString $ shortByteString
    BSLC.putStrLn lazyByteStringD
    print lazyByteStringD
実行結果
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"

ShortByteString から直接 Lazy ByteString を作ることはできません。

参考「unpack - Data.ByteString.Short

4. 空文字列の場合

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    let lazyByteStringA = BSLC.empty
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = mempty
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    let lazyByteStringC = BSB.toLazyByteString mempty
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC
実行結果

""

""

""

5. その他の型から作る場合

他にも様々な型の値から Lazy ByteString を作ることができます。

ここでは例として一部のみ載せます。他の作り方に関しては公式ドキュメント等を参照して下さい。

参考「Data.ByteString.Builder
参考「Data.ByteString.Lazy
参考「Data.ByteString.Lazy.Char8

import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy.Char8 as BSLC

main :: IO ()
main = do

    let lazyByteStringA = BSB.toLazyByteString . BSB.word32BE $ 0x63617420
    BSLC.putStrLn lazyByteStringA
    print lazyByteStringA

    let lazyByteStringB = BSB.toLazyByteString . BSB.lazyByteStringHex $ lazyByteStringA
    BSLC.putStrLn lazyByteStringB
    print lazyByteStringB

    let lazyByteStringC = BSB.toLazyByteString . BSB.word32HexFixed $ 0x63617420
    BSLC.putStrLn lazyByteStringC
    print lazyByteStringC
実行結果
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?