This module is intended to be imported qualified, to avoid name
clashes with Prelude functions. eg.

import qualified Data.ByteString.Char8 as C

The Char8 interface to bytestrings provides an instance of IsString
for the ByteString type, enabling you to use string literals, and
have them implicitly packed to ByteStrings.
Use {-# LANGUAGE OverloadedStrings #-} to enable this.

Accumulating maps

The mapAccumL function behaves like a combination of map and
foldl; it applies a function to each element of a ByteString,
passing an accumulating parameter from left to right, and returning a
final value of this accumulator together with the new list.

The mapAccumR function behaves like a combination of map and
foldr; it applies a function to each element of a ByteString,
passing an accumulating parameter from right to left, and returning a
final value of this accumulator together with the new ByteString.

O(n), where n is the length of the result. The unfoldr
function is analogous to the List 'unfoldr'. unfoldr builds a
ByteString from a seed value. The function takes the element and
returns Nothing if it is done producing the ByteString or returns
Just(a,b), in which case, a is the next character in the string,
and b is the seed value for further production.

O(n) Like unfoldr, unfoldrN builds a ByteString from a seed
value. However, the length of the result is limited by the first
argument to unfoldrN. This function is more efficient than unfoldr
when the maximum length of the result is known.

The group function takes a ByteString and returns a list of
ByteStrings such that the concatenation of the result is equal to the
argument. Moreover, each sublist in the result contains only equal
elements. For example,

group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]

It is a special case of groupBy, which allows the programmer to
supply their own equality test. It is about 40% faster than
groupBy (==)

O(n) Splits a ByteString into components delimited by
separators, where the predicate returns True for a separator element.
The resulting components do not contain the separators. Two adjacent
separators result in an empty component in the output. eg.

Zipping and unzipping ByteStrings

O(n)zip takes two ByteStrings and returns a list of
corresponding pairs of Chars. If one input ByteString is short,
excess elements of the longer ByteString are discarded. This is
equivalent to a pair of unpack operations, and so space
usage may be large for multi-megabyte ByteStrings

zipWith generalises zip by zipping with the function given as
the first argument, instead of a tupling function. For example,
zipWith (+) is applied to two ByteStrings to produce the list
of corresponding sums.

Ordered ByteStrings

Reading from ByteStrings

readInt reads an Int from the beginning of the ByteString. If there is no
integer at the beginning of the string, it returns Nothing, otherwise
it just returns the int read, and the rest of the string.

readInteger reads an Integer from the beginning of the ByteString. If
there is no integer at the beginning of the string, it returns Nothing,
otherwise it just returns the int read, and the rest of the string.

Low level CString conversions

Copying ByteStrings

O(n) Make a copy of the ByteString with its own storage.
This is mainly useful to allow the rest of the data pointed
to by the ByteString to be garbage collected, for example
if a large string has been read in, and only a small part of it
is needed in the rest of the program.

Packing CStrings and pointers

O(n). Construct a new ByteString from a CString. The
resulting ByteString is an immutable copy of the original
CString, and is managed on the Haskell heap. The original
CString must be null terminated.

O(n). Construct a new ByteString from a CStringLen. The
resulting ByteString is an immutable copy of the original CStringLen.
The ByteString is a normal Haskell value and will be managed on the
Haskell heap.

ByteString I/O uses binary mode, without any character decoding
or newline conversion. The fact that it does not respect the Handle
newline mode is considered a flaw and may be changed in a future version.

The interact function takes a function of type ByteString -> ByteString
as its argument. The entire input from the standard input device is passed
to this function as its argument, and the resulting string is output on the
standard output device.

Files

Read an entire file strictly into a ByteString. This is far more
efficient than reading the characters into a String and then using
pack. It also may be more efficient than opening the file and
reading it using hGet.

I/O with Handles

This function reads chunks at a time, doubling the chunksize on each
read. The final buffer is then realloced to the appropriate size. For
files > half of available memory, this may lead to memory exhaustion.
Consider using readFile in this case.

As with hGet, the string representation in the file is assumed to
be ISO-8859-1.

The Handle is closed once the contents have been read,
or if an exception is thrown.

Read a ByteString directly from the specified Handle. This
is far more efficient than reading the characters into a String
and then using pack. First argument is the Handle to read from,
and the second is the number of bytes to read. It returns the bytes
read, up to n, or null if EOF has been reached.

Like hGet, except that a shorter ByteString may be returned
if there are not enough bytes immediately available to satisfy the
whole request. hGetSome only blocks if there is no data
available, and EOF has not yet been reached.

hGetNonBlocking is similar to hGet, except that it will never block
waiting for data to become available, instead it returns only whatever data
is available. If there is no data available to be read, hGetNonBlocking
returns empty.

Note: on Windows and with Haskell implementation other than GHC, this
function does not work correctly; it behaves identically to hGet.

Similar to hPut except that it will never block. Instead it returns
any tail that did not get written. This tail may be empty in the case that
the whole string was written, or the whole original string if nothing was
written. Partial writes are also possible.

Note: on Windows and with Haskell implementation other than GHC, this
function does not work correctly; it behaves identically to hPut.