Изучай Haskell во имя добра! (Липовача) - страница 150

, только в сигнатурах функций будет указан тип >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))

Это полезно, если у вас есть множество маленьких строгих строк байтов и вы хотите эффективно обработать их, не объединяя их в памяти в одну большую строгую строку.