上記のコメントで @sclv が述べたように、遅延バイト文字列は厳密なバイト文字列の単なるリストです。lazy ByteString を strict に変換するには 2 つの方法があります (ソース: haskell メーリング リストでの toStrict 関数の追加に関するディスカッション) - 以下の電子メール スレッドからの関連コード:
まず、関連するライブラリ:
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Internal as BLI
import Foreign.ForeignPtr
import Foreign.Ptr
アプローチ 1 (@sclv と同じ):
toStrict1 :: BL.ByteString -> B.ByteString
toStrict1 = B.concat . BL.toChunks
アプローチ 2:
toStrict2 :: BL.ByteString -> B.ByteString
toStrict2 BLI.Empty = B.empty
toStrict2 (BLI.Chunk c BLI.Empty) = c
toStrict2 lb = BI.unsafeCreate len $ go lb
where
len = BLI.foldlChunks (\l sb -> l + B.length sb) 0 lb
go BLI.Empty _ = return ()
go (BLI.Chunk (BI.PS fp s l) r) ptr =
withForeignPtr fp $ \p -> do
BI.memcpy ptr (p `plusPtr` s) (fromIntegral l)
go r (ptr `plusPtr` l)
パフォーマンスが気になる場合は、上記のメール スレッドを確認することをお勧めします。基準ベンチマークもあります。これらのベンチマークでは、toStrict2 は toStrict1 よりも高速です。