, только в сигнатурах функций будет указан тип
>ByteString
вместо
>[a]
и
>Word8
вместо
>a
. Функции в этом модуле работают со значениями типа
>ByteString
так же, как одноимённые функции – со списками. Поскольку имена совпадают, нам придётся сделать уточнённый импорт в скрипте и затем загрузить этот скрипт в интерпретатор GHCi для того, чтобы поэкспериментировать с типом
>ByteString
.
>import qualified Data.ByteString.Lazy as B
>import qualified Data.ByteString as S
Модуль B содержит ленивые строки байтов и функции, модуль S – строгие. Главным образом мы будем использовать ленивую версию.
Функция >pack
имеет сигнатуру >pack :: [Word8] –> ByteString
. Это означает, что она принимает список байтов типа Word8 и возвращает значение типа >ByteString
. Можно думать, будто функция принимает ленивый список и делает его менее ленивым, так что он ленив только блоками по 64 Кб.
Что за тип >Word8
? Он похож на >Int
, но имеет значительно меньший диапазон, а именно 0 – 255. Тип представляет собой восьми битовое число. Так же как и >Int
, он имеет экземпляр класса >Num
. Например, мы знаем, что число 5 полиморфно, а значит, оно может вести себя как любой числовой тип. В том числе – принимать тип >Word8
.
>ghci> B.pack [99,97,110]
>Chunk "can" Empty
>ghci> B.pack [98..120]
>Chunk "bcdefghijklmnopqrstuvwx" Empty
Как можно видеть, >Word8
не доставляет много хлопот, поскольку система типов определяет, что числа должны быть преобразованы к нему. Если вы попытаетесь использовать большое число, например 336, в качестве значения типа >Word8
, число будет взято по модулю 256, то есть сохранится 80.
Мы упаковали всего несколько значений в тип >ByteString
; они уместились в один блок. Значение >Empty
– это нечто вроде >[]
для списков.
Если нужно просмотреть байтовую строку байт за байтом, её нужно распаковать. Функция >unpack
обратна функции >pack
. Она принимает строку байтов и возвращает список байтов. Вот пример:
>ghci> let by = B.pack [98,111,114,116]
>ghci> by
>Chunk "bort" Empty
>ghci> B.unpack by
>[98,111,114,116]
Вы также можете преобразовывать байтовые строки из строгих в ленивые и наоборот. Функция >fromChunks
принимает список строгих строк и преобразует их в ленивую строку. Соответственно, функция >toChunks
принимает ленивую строку байтов и преобразует её в список строгих строк.
>ghci> B.fromChunks [S.pack [40,41,42], S.pack [43,44,45], S.pack [46,47,48]]
>Chunk "()*" (Chunk "+,–" (Chunk "./0" Empty))
Это полезно, если у вас есть множество маленьких строгих строк байтов и вы хотите эффективно обработать их, не объединяя их в памяти в одну большую строгую строку.