This module implements bag and set operations on ordered lists. For the
purposes of this module, a "bag" (or "multiset") is a non-decreasing
list, whereas a "set" is a strictly ascending list. Bags are sorted
lists that may contain duplicates, whereas sets are sorted lists that
do not contain duplicates.

Except for the nub, sort, nubSort, and isSorted families of
functions, every function assumes that any list arguments are sorted
lists. Assuming this precondition is met, every resulting list is also
sorted.

Because isect handles multisets correctly, it does not return results
comparable to Data.List.intersect on them. Thus isect
is more than just a more efficient intersect on ordered lists. Similar
statements apply to other associations between functions this module and
functions in Data.List, such as union and Data.List.union.

All functions in this module are left biased. Elements that appear in
earlier arguments have priority over equal elements that appear in later
arguments, and elements that appear earlier in a single list have
priority over equal elements that appear later in that list.

The has function returns True if the element appears in the list;
it is equivalent to member except the order of the arguments is reversed,
making it a function from an ordered list to its characteristic function.

Set-like operations

The isect function computes the intersection of two ordered lists.
An element occurs in the output as many times as the minimum number of
occurrences in either input. If either input is a set, then the output
is a set.

The union function computes the union of two ordered lists.
An element occurs in the output as many times as the maximum number
of occurrences in either input. The output is a set if and only if
both inputs are sets.

The minus function computes the difference of two ordered lists.
An element occurs in the output as many times as it occurs in
the first input, minus the number of occurrences in the second input.
If the first input is a set, then the output is a set.

The minus' function computes the difference of two ordered lists.
The result consists of elements from the first list that do not appear
in the second list. If the first input is a set, then the output is
a set.

The xunion function computes the exclusive union of two ordered lists.
An element occurs in the output as many times as the absolute difference
between the number of occurrences in the inputs. If both inputs
are sets, then the output is a set.

The merge function combines all elements of two ordered lists.
An element occurs in the output as many times as the sum of the
occurrences in both lists. The output is a set if and only if
the inputs are disjoint sets.

The mergeAll function merges a (potentially) infinite number of
ordered lists, under the assumption that the heads of the inner lists
are sorted. An element is duplicated in the result as many times as
the total number of occurrences in all inner lists.

The mergeAll function is closely related to foldrmerge [].
The former does not assume that the outer list is finite, whereas
the latter does not assume that the heads of the inner lists are sorted.
When both sets of assumptions are met, these two functions are
equivalent.

This implementation of mergeAll uses a tree of comparisons, and is
based on input from Dave Bayer, Heinrich Apfelmus, Omar Antolin Camarena,
and Will Ness. See CHANGES for details.

The unionAll computes the union of a (potentially) infinite number
of lists, under the assumption that the heads of the inner lists
are sorted. The result will duplicate an element as many times as
the maximum number of occurrences in any single list. Thus, the result
is a set if and only if every inner list is a set.

The unionAll function is closely related to foldrunion [].
The former does not assume that the outer list is finite, whereas
the latter does not assume that the heads of the inner lists are sorted.
When both sets of assumptions are met, these two functions are
equivalent.

Note that there is no simple way to express unionAll in terms of
mergeAll or vice versa on arbitrary valid inputs. They are related
via nub however, as nub . mergeAll == unionAll . mapnub.
If every list is a set, then map nub == id, and in this special case
(and only in this special case) does nub . mergeAll == unionAll.

This implementation of unionAll uses a tree of comparisons, and is
based on input from Dave Bayer, Heinrich Apfelmus, Omar Antolin Camarena,
and Will Ness. See CHANGES for details.

The nubBy function is the greedy algorithm that returns a
sublist of its input such that:

isSortedBy pred (nubBy pred xs) == True

This is true for all lists, not just ordered lists, and all binary
predicates, not just total orders. On infinite lists, this statement
is true in a certain mathematical sense, but not a computational one.

This variant of sortOn recomputes the sorting key every comparison.
This can be better for functions that are cheap to compute.
This is definitely better for projections, as the decorate-sort-undecorate
saves nothing and adds two traversals of the list and extra memory
allocation.

The nubSort function is equivalent to nub.sort, except
that duplicates are removed as it sorts. It is essentially the same
implementation as Data.List.sort, with merge replaced by union.
Thus the performance of nubSort should better than or nearly equal
to sort alone. It is faster than both sort and nub.sort
when the input contains significant quantities of duplicated elements.

Miscellaneous folds

The function foldt plus zero computes the sum of a list using
a sequence of balanced trees of operations. Given an appropriate plus
operator, this function can be productive on an infinite list, hence it
is lazier than foldt'. foldt is used in the implementation of
mergeAll and unionAll.

The function foldt' plus zero computes the sum of a list
using a balanced tree of operations. foldt' necessarily diverges
on infinite lists, hence it is a stricter variant of foldt.
foldt' is used in the implementation of sort and nubSort.