An efficient implementation of maps from integer keys to values
(dictionaries).

API of this module is strict in the keys, but lazy in the values.
If you need value-strict maps, use Strict instead.
The IntMap type itself is shared between the lazy and strict modules,
meaning that the same IntMap value can be passed to functions in
both modules (although that is rarely needed).

These modules are intended to be imported qualified, to avoid name
clashes with Prelude functions, e.g.

The implementation is based on big-endian patricia trees. This data
structure performs especially well on binary operations like union
and intersection. However, my benchmarks show that it is also
(much) faster on insertions and deletions when compared to a generic
size-balanced map implementation (see Data.Map).

Operation comments contain the operation time complexity in
the Big-O notation http://en.wikipedia.org/wiki/Big_O_notation.
Many operations have a worst-case complexity of O(min(n,W)).
This means that the operation can become linear in the number of
elements with a maximum of W -- the number of bits in an Int
(32 or 64).

O(min(n,W)). Insert with a combining function.
insertWith f key value mp
will insert the pair (key, value) into mp if key does
not exist in the map. If the key does exist, the function will
insert f new_value old_value.

O(min(n,W)). Insert with a combining function.
insertWithKey f key value mp
will insert the pair (key, value) into mp if key does
not exist in the map. If the key does exist, the function will
insert f key new_value old_value.

O(n+m). Difference with a combining function. When two equal keys are
encountered, the combining function is applied to the key and both values.
If it returns Nothing, the element is discarded (proper set difference).
If it returns (Just y), the element is updated with a new value y.

Universal combining function

O(n+m). A high-performance universal combining function. Using
mergeWithKey, all combining functions can be defined without any loss of
efficiency (with exception of union, difference and intersection,
where sharing of some nodes is lost with mergeWithKey).

Please make sure you know what is going on when using mergeWithKey,
otherwise you can be surprised by unexpected code growth or even
corruption of the data structure.

When calling mergeWithKey combine only1 only2, a function combining two
IntMaps is created, such that

if a key is present in both maps, it is passed with both corresponding
values to the combine function. Depending on the result, the key is either
present in the result with specified value, or is left out;

a nonempty subtree present only in the first map is passed to only1 and
the output is added to the result;

a nonempty subtree present only in the second map is passed to only2 and
the output is added to the result.

The only1 and only2 methods must return a map with a subset (possibly empty) of the keys of the given map.
The values can be modified arbitrarily. Most common variants of only1 and
only2 are id and constempty, but for example map f or
filterWithKey f could be used for any f.

O(n*min(n,W)).
mapKeysMonotonic f s == mapKeys f s, but works only when f
is strictly monotonic.
That is, for any values x and y, if x < y then f x < f y.
The precondition is not checked.
Semi-formally, we have:

Submap

O(n+m).
The expression (isSubmapOfBy f m1 m2) returns True if
all keys in m1 are in m2, and when f returns True when
applied to their respective values. For example, the following
expressions are all True:

O(n+m). Is this a proper submap? (ie. a submap but not equal).
The expression (isProperSubmapOfBy f m1 m2) returns True when
m1 and m2 are not equal,
all keys in m1 are in m2, and when f returns True when
applied to their respective values. For example, the following
expressions are all True:

O(n). The expression (showTreeWith hang wide map) shows
the tree that implements the map. If hang is
True, a hanging tree is shown otherwise a rotated tree is shown. If
wide is True, an extra wide version is shown.