Introduction

Welcome to ListLike.

This module provides abstractions over typical list operations.
It is designed to let you freely interchange different ways to represent
sequences of data. It works with lists, various types of ByteStrings,
and much more.

In this module, you'll find generic versions of most of the functions
you're used to using in the Prelude, Data.List, and System.IO.
They carry the
same names, too. Therefore, you'll want to be careful how you import
the module. I suggest using:

import qualified Data.ListLike as LL

Then, you can use LL.fold, LL.map, etc. to get the generic version of
the functions you want. Alternatively, you can hide the other versions
from Prelude and import specific generic functions from here, such as:

import Prelude hiding (map)
import Data.ListLike (map)

The module Data.ListLike actually simply re-exports the items found
in a number of its sub-modules. If you want a smaller subset of
Data.ListLike, look at the documentation for its sub-modules and import
the relevant one.

In most cases, functions here can act as drop-in replacements for their
list-specific counterparts. They will use the same underlying implementations
for lists, so there should be no performance difference.

You can make your own types instances of ListLike as well. For more
details, see the notes for the ListLike typeclass.

Input and Output

An extension to ListLike for those data types that support
I/O. These functions mirror those in System.IO for the most part. They
also share the same names; see the comments in Data.ListLike for help
importing them.

Note that some types may not be capable of lazy reading or writing.
Therefore, the usual semantics of System.IO functions regarding laziness
may or may not be available from a particular implementation.

Arrays

ListLike functions that take an index always take a 0-based index
for compatibility with other ListLike instances.
This is translated by the instance functions into the proper offset from
the bounds in the Array.

ListLike functions preserve the original Array index numbers when
possible. Functions such as cons will reduce the lower bound to do
their job. snoc and append increase the upper bound. drop raises
the lower bound and take lowers the upper bound.

Functions that change the length of the array by an amount not known
in advance, such as filter, will generate a new array with the lower
bound set to 0. Furthermore, these functions cannot operate on infinite
lists because they must know their length in order to generate the
array. hGetContents and its friends will therefore require the
entire file to be read into memory before processing is possible.

ByteStrings

ByteString ListLike instances operate on Word8 elements. This is because
both Data.ByteString.ByteString and Data.ByteString.Char8.ByteString have
the same underlying type. If you wish to use the Char8 representation,
the newtype wrappers CharString and CharStringLazy are available.

The lazy ByteStream module implements fewer funtions than the strict
ByteStream module. In some cases, default implementations are used.
In others, notably related to I/O, the lazy ByteStreams are converted
back and forth to strict ones as appropriate.

Base Typeclasses

The ListLike class

It is worth noting that types such as Map can be instances of
ListLike. Due to their specific ways of operating, they may not behave
in the expected way in some cases. For instance, cons may not increase
the size of a map if the key you have given is already in the map; it will
just replace the value already there.

Apply a function to each element, returning any other
valid ListLike. rigidMap will always be at least
as fast, if not faster, than this function and is recommended
if it will work for your purposes. See also mapM.

Like map, but without the possibility of changing the type of
the item. This can have performance benefits for things such as
ByteStrings, since it will let the ByteString use its native
low-level map implementation.

Inserts the element at the last place where it is still less than or
equal to the next element. On data types that do not preserve
ordering, or enforce their own ordering, the result may not
be what you expect. On types such as maps, this may result in
changing an existing item. See also insertBy.

The InfiniteListLike class

An extension to ListLike for those data types that are capable
of dealing with infinite lists. Some ListLike functions are capable
of working with finite or infinite lists. The functions here require
infinite list capability in order to work at all.