-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Assorted concrete container types
--   
--   This package contains efficient general-purpose implementations of
--   various immutable container types including sets, maps, sequences,
--   trees, and graphs.
--   
--   For a walkthrough of what this package provides with examples of
--   common operations see the <a>containers introduction</a>.
--   
--   The declared cost of each operation is either worst-case or amortized,
--   but remains valid even if structures are shared.
@package containers
@version 0.8


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Description</h1>
--   
--   This module defines common constructs used by both <a>Data.IntSet</a>
--   and <a>Data.IntMap</a>.
module Data.IntSet.Internal.IntTreeCommons
type Key = Int

-- | A <tt>Prefix</tt> represents some prefix of high-order bits of an
--   <tt>Int</tt>.
--   
--   A <tt>Prefix</tt> is usually considered in the context of a <a>Bin</a>
--   or <a>Bin</a>.
newtype Prefix
Prefix :: Int -> Prefix
[unPrefix] :: Prefix -> Int

-- | Whether the <tt>Int</tt> does not start with the given
--   <tt>Prefix</tt>.
--   
--   An <tt>Int</tt> starts with a <tt>Prefix</tt> if it shares the high
--   bits with the internal <tt>Int</tt> value of the <tt>Prefix</tt> up to
--   the mask bit.
--   
--   <tt>nomatch</tt> is usually used to determine whether a key belongs in
--   a <tt>Bin</tt>, since all keys in a <tt>Bin</tt> share a
--   <tt>Prefix</tt>.
nomatch :: Int -> Prefix -> Bool

-- | Whether the <tt>Int</tt> is to the left of the split created by a
--   <tt>Bin</tt> with this <tt>Prefix</tt>.
--   
--   This does not imply that the <tt>Int</tt> belongs in this
--   <tt>Bin</tt>. That fact is usually determined first using
--   <tt>nomatch</tt>.
left :: Int -> Prefix -> Bool

-- | Whether this <tt>Prefix</tt> splits a <tt>Bin</tt> at the sign bit.
--   
--   This can only be True at the top level. If it is true, the left child
--   contains non-negative keys and the right child contains negative keys.
signBranch :: Prefix -> Bool

-- | A <tt>TreeTreeBranch</tt> is returned by <a>treeTreeBranch</a> to
--   indicate how two <tt>Bin</tt>s relate to each other.
--   
--   Consider that <tt>A</tt> and <tt>B</tt> are the <tt>Bin</tt>s whose
--   <tt>Prefix</tt>es are given to <tt>treeTreeBranch</tt> as the first
--   and second arguments respectively.
data TreeTreeBranch

-- | A contains B in the left child
ABL :: TreeTreeBranch

-- | A contains B in the right child
ABR :: TreeTreeBranch

-- | B contains A in the left child
BAL :: TreeTreeBranch

-- | B contains A in the right child
BAR :: TreeTreeBranch

-- | A and B have equal prefixes
EQL :: TreeTreeBranch

-- | A and B have prefixes that do not match
NOM :: TreeTreeBranch
treeTreeBranch :: Prefix -> Prefix -> TreeTreeBranch

-- | The prefix of key <tt>i</tt> up to (but not including) the switching
--   bit <tt>m</tt>.
mask :: Key -> Int -> Int

-- | The first switching bit where the two prefixes disagree.
--   
--   Precondition for defined behavior: p1 /= p2
branchMask :: Int -> Int -> Int
i2w :: Int -> Word
data Order
A_LT_B :: Order
A_Prefix_B :: Order
A_EQ_B :: Order
B_Prefix_A :: Order
A_GT_B :: Order
instance GHC.Internal.Classes.Eq Data.IntSet.Internal.IntTreeCommons.Prefix
instance GHC.Internal.TH.Lift.Lift Data.IntSet.Internal.IntTreeCommons.Prefix


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Sets (internals)</h1>
--   
--   The <tt><a>Set</a> e</tt> type represents a set of elements of type
--   <tt>e</tt>. Most operations require that <tt>e</tt> be an instance of
--   the <a>Ord</a> class. A <a>Set</a> is strict in its elements.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Set</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
module Data.Set.Internal

-- | A set of values <tt>a</tt>.
data Set a
Bin :: Size -> a -> Set a -> Set a -> Set a
Tip :: Set a
type Size = Int

-- | &lt;math&gt;. See <a>difference</a>.
(\\) :: Ord a => Set a -> Set a -> Set a
infixl 9 \\

-- | &lt;math&gt;. Is this the empty set?
null :: Set a -> Bool

-- | &lt;math&gt;. The number of elements in the set.
size :: Set a -> Int

-- | &lt;math&gt;. Is the element in the set?
member :: Ord a => a -> Set a -> Bool

-- | &lt;math&gt;. Is the element not in the set?
notMember :: Ord a => a -> Set a -> Bool

-- | &lt;math&gt;. Find largest element smaller than the given one.
--   
--   <pre>
--   lookupLT 3 (fromList [3, 5]) == Nothing
--   lookupLT 5 (fromList [3, 5]) == Just 3
--   </pre>
lookupLT :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find smallest element greater than the given one.
--   
--   <pre>
--   lookupGT 4 (fromList [3, 5]) == Just 5
--   lookupGT 5 (fromList [3, 5]) == Nothing
--   </pre>
lookupGT :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find largest element smaller or equal to the given one.
--   
--   <pre>
--   lookupLE 2 (fromList [3, 5]) == Nothing
--   lookupLE 4 (fromList [3, 5]) == Just 3
--   lookupLE 5 (fromList [3, 5]) == Just 5
--   </pre>
lookupLE :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find smallest element greater or equal to the given one.
--   
--   <pre>
--   lookupGE 3 (fromList [3, 5]) == Just 3
--   lookupGE 4 (fromList [3, 5]) == Just 5
--   lookupGE 6 (fromList [3, 5]) == Nothing
--   </pre>
lookupGE :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. <tt>(s1 `isSubsetOf` s2)</tt> indicates whether
--   <tt>s1</tt> is a subset of <tt>s2</tt>.
--   
--   <pre>
--   s1 `isSubsetOf` s2 = all (<a>`member`</a> s2) s1
--   s1 `isSubsetOf` s2 = null (s1 <a>`difference`</a> s2)
--   s1 `isSubsetOf` s2 = s1 <a>`union`</a> s2 == s2
--   s1 `isSubsetOf` s2 = s1 <a>`intersection`</a> s2 == s1
--   </pre>
isSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. <tt>(s1 `isProperSubsetOf` s2)</tt> indicates whether
--   <tt>s1</tt> is a proper subset of <tt>s2</tt>.
--   
--   <pre>
--   s1 `isProperSubsetOf` s2 = s1 <a>`isSubsetOf`</a> s2 &amp;&amp; s1 /= s2
--   </pre>
isProperSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. Check whether two sets are disjoint (i.e., their
--   intersection is empty).
--   
--   <pre>
--   disjoint (fromList [2,4,6])   (fromList [1,3])     == True
--   disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
--   disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
--   disjoint (fromList [])        (fromList [])        == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. The empty set.
empty :: Set a

-- | &lt;math&gt;. Create a singleton set.
singleton :: a -> Set a

-- | &lt;math&gt;. Insert an element in a set. If the set already contains
--   an element equal to the given value, it is replaced with the new
--   value.
insert :: Ord a => a -> Set a -> Set a

-- | &lt;math&gt;. Delete an element from a set.
delete :: Ord a => a -> Set a -> Set a

-- | &lt;math&gt; <tt>(<a>alterF</a> f x s)</tt> can delete or insert
--   <tt>x</tt> in <tt>s</tt> depending on whether an equal element is
--   found in <tt>s</tt>.
--   
--   In short:
--   
--   <pre>
--   <a>member</a> x &lt;$&gt; <a>alterF</a> f x s = f (<a>member</a> x s)
--   </pre>
--   
--   Note that unlike <a>insert</a>, <a>alterF</a> will <i>not</i> replace
--   an element equal to the given value.
--   
--   Note: <a>alterF</a> is a variant of the <tt>at</tt> combinator from
--   <a>Control.Lens.At</a>.
alterF :: (Ord a, Functor f) => (Bool -> f Bool) -> a -> Set a -> f (Set a)

-- | &lt;math&gt;. Calculate the power set of a set: the set of all its
--   subsets.
--   
--   <pre>
--   t <a>`member`</a> powerSet s == t <a>`isSubsetOf`</a> s
--   </pre>
--   
--   Example:
--   
--   <pre>
--   powerSet (fromList [1,2,3]) =
--     fromList $ map fromList [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
--   </pre>
powerSet :: Set a -> Set (Set a)

-- | &lt;math&gt;. The union of two sets, preferring the first set when
--   equal elements are encountered.
union :: Ord a => Set a -> Set a -> Set a

-- | The union of the sets in a Foldable structure : (<tt><a>unions</a> ==
--   <a>foldl</a> <a>union</a> <a>empty</a></tt>).
unions :: (Foldable f, Ord a) => f (Set a) -> Set a

-- | &lt;math&gt;. Difference of two sets.
--   
--   Return elements of the first set not existing in the second set.
--   
--   <pre>
--   difference (fromList [5, 3]) (fromList [5, 7]) == singleton 3
--   </pre>
difference :: Ord a => Set a -> Set a -> Set a

-- | &lt;math&gt;. The intersection of two sets. Elements of the result
--   come from the first set, so for example
--   
--   <pre>
--   import qualified Data.Set as S
--   data AB = A | B deriving Show
--   instance Ord AB where compare _ _ = EQ
--   instance Eq AB where _ == _ = True
--   main = print (S.singleton A `S.intersection` S.singleton B,
--                 S.singleton B `S.intersection` S.singleton A)
--   </pre>
--   
--   prints <tt>(fromList [A],fromList [B])</tt>.
intersection :: Ord a => Set a -> Set a -> Set a

-- | The intersection of a series of sets. Intersections are performed
--   left-to-right.
intersections :: Ord a => NonEmpty (Set a) -> Set a

-- | &lt;math&gt;. The symmetric difference of two sets.
--   
--   The result contains elements that appear in exactly one of the two
--   sets.
--   
--   <pre>
--   symmetricDifference (fromList [0,2,4,6]) (fromList [0,3,6,9]) == fromList [2,3,4,9]
--   </pre>
symmetricDifference :: Ord a => Set a -> Set a -> Set a

-- | &lt;math&gt;. Calculate the Cartesian product of two sets.
--   
--   <pre>
--   cartesianProduct xs ys = fromList $ liftA2 (,) (toList xs) (toList ys)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   cartesianProduct (fromList [1,2]) (fromList ['a','b']) =
--     fromList [(1,'a'), (1,'b'), (2,'a'), (2,'b')]
--   </pre>
cartesianProduct :: Set a -> Set b -> Set (a, b)

-- | &lt;math&gt;. Calculate the disjoint union of two sets.
--   
--   <pre>
--   disjointUnion xs ys = map Left xs <a>`union`</a> map Right ys
--   </pre>
--   
--   Example:
--   
--   <pre>
--   disjointUnion (fromList [1,2]) (fromList ["hi", "bye"]) =
--     fromList [Left 1, Left 2, Right "hi", Right "bye"]
--   </pre>
disjointUnion :: Set a -> Set b -> Set (Either a b)

-- | <tt>Set</tt>s form a <a>Semigroup</a> under <a>intersection</a>.
newtype Intersection a
Intersection :: Set a -> Intersection a
[getIntersection] :: Intersection a -> Set a

-- | &lt;math&gt;. Filter all elements that satisfy the predicate.
filter :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Take while a predicate on the elements holds. The user
--   is responsible for ensuring that for all elements <tt>j</tt> and
--   <tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
--   note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
--   takeWhileAntitone p = <a>filter</a> p
--   </pre>
takeWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Drop while a predicate on the elements holds. The user
--   is responsible for ensuring that for all elements <tt>j</tt> and
--   <tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
--   note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
--   dropWhileAntitone p = <a>filter</a> (not . p)
--   </pre>
dropWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Divide a set at the point where a predicate on the
--   elements stops holding. The user is responsible for ensuring that for
--   all elements <tt>j</tt> and <tt>k</tt> in the set, <tt>j &lt; k ==&gt;
--   p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partition p xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first element and to fail
--   after the last element).
spanAntitone :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. Partition the set into two sets, one with all elements
--   that satisfy the predicate and one with all elements that don't
--   satisfy the predicate. See also <a>split</a>.
partition :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. The expression (<tt><a>split</a> x set</tt>) is a pair
--   <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements of
--   <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
--   elements of <tt>set</tt> greater than <tt>x</tt>.
split :: Ord a => a -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot element was found in the original set.
splitMember :: Ord a => a -> Set a -> (Set a, Bool, Set a)

-- | &lt;math&gt;. Decompose a set into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a set in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first subset less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList [1..6]) ==
--     [fromList [1,2,3],fromList [4],fromList [5,6]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   subsets, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Set a -> [Set a]

-- | &lt;math&gt;. Look up the <i>index</i> of an element, which is its
--   zero-based index in the sorted sequence of elements. The index is a
--   number from <i>0</i> up to, but not including, the <a>size</a> of the
--   set.
--   
--   <pre>
--   isJust   (lookupIndex 2 (fromList [5,3])) == False
--   fromJust (lookupIndex 3 (fromList [5,3])) == 0
--   fromJust (lookupIndex 5 (fromList [5,3])) == 1
--   isJust   (lookupIndex 6 (fromList [5,3])) == False
--   </pre>
lookupIndex :: Ord a => a -> Set a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of an element, which is its
--   zero-based index in the sorted sequence of elements. The index is a
--   number from <i>0</i> up to, but not including, the <a>size</a> of the
--   set. Calls <a>error</a> when the element is not a <a>member</a> of the
--   set.
--   
--   <pre>
--   findIndex 2 (fromList [5,3])    Error: element is not in the set
--   findIndex 3 (fromList [5,3]) == 0
--   findIndex 5 (fromList [5,3]) == 1
--   findIndex 6 (fromList [5,3])    Error: element is not in the set
--   </pre>
findIndex :: Ord a => a -> Set a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sorted sequence of elements. If the
--   <i>index</i> is out of range (less than zero, greater or equal to
--   <a>size</a> of the set), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [5,3]) == 3
--   elemAt 1 (fromList [5,3]) == 5
--   elemAt 2 (fromList [5,3])    Error: index out of range
--   </pre>
elemAt :: Int -> Set a -> a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sorted sequence of elements. If the
--   <i>index</i> is out of range (less than zero, greater or equal to
--   <a>size</a> of the set), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0    (fromList [5,3]) == singleton 5
--   deleteAt 1    (fromList [5,3]) == singleton 3
--   deleteAt 2    (fromList [5,3])    Error: index out of range
--   deleteAt (-1) (fromList [5,3])    Error: index out of range
--   </pre>
deleteAt :: Int -> Set a -> Set a

-- | &lt;math&gt;. Take a given number of elements in order, beginning with
--   the smallest ones.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Set a -> Set a

-- | &lt;math&gt;. Drop a given number of elements in order, beginning with
--   the smallest ones.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Set a -> Set a

-- | &lt;math&gt;. Split a set at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. <tt><a>map</a> f s</tt> is the set obtained by applying
--   <tt>f</tt> to each element of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   It's worth noting that the size of the result may be smaller if, for
--   some <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: Ord b => (a -> b) -> Set a -> Set b

-- | &lt;math&gt;. <tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but
--   works only when <tt>f</tt> is strictly increasing. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapMonotonic f s == map f s
--       where ls = toList s
--   </pre>
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>map</a> if the precondition may not hold.
mapMonotonic :: (a -> b) -> Set a -> Set b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toAscList set = foldr (:) [] set
--   </pre>
foldr :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toDescList set = foldl (flip (:)) [] set
--   </pre>
foldl :: (a -> b -> a) -> a -> Set b -> a

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Set b -> a

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator.

-- | <i>Deprecated: Use Data.Set.foldr instead</i>
fold :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. The minimal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMin :: Set a -> Maybe a

-- | &lt;math&gt;. The maximal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMax :: Set a -> Maybe a

-- | &lt;math&gt;. The minimal element of the set. Calls <a>error</a> if
--   the set is empty.
findMin :: Set a -> a

-- | &lt;math&gt;. The maximal element of the set. Calls <a>error</a> if
--   the set is empty.
findMax :: Set a -> a

-- | &lt;math&gt;. Delete the minimal element. Returns an empty set if the
--   set is empty.
deleteMin :: Set a -> Set a

-- | &lt;math&gt;. Delete the maximal element. Returns an empty set if the
--   set is empty.
deleteMax :: Set a -> Set a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: Set a -> (a, Set a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: Set a -> (a, Set a)

-- | &lt;math&gt;. Retrieves the maximal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: Set a -> Maybe (a, Set a)

-- | &lt;math&gt;. Retrieves the minimal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: Set a -> Maybe (a, Set a)

-- | &lt;math&gt;. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: Set a -> [a]

-- | &lt;math&gt;. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: Set a -> [a]

-- | &lt;math&gt;. Create a set from a list of elements.
--   
--   If the elements are in non-decreasing order, this function takes
--   &lt;math&gt; time.
fromList :: Ord a => [a] -> Set a

-- | &lt;math&gt;. Convert the set to an ascending list of elements.
--   Subject to list fusion.
toAscList :: Set a -> [a]

-- | &lt;math&gt;. Convert the set to a descending list of elements.
--   Subject to list fusion.
toDescList :: Set a -> [a]

-- | &lt;math&gt;. Build a set from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromAscList :: Eq a => [a] -> Set a

-- | &lt;math&gt;. Build a set from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctAscList :: [a] -> Set a

-- | &lt;math&gt;. Build a set from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDescList :: Eq a => [a] -> Set a

-- | &lt;math&gt;. Build a set from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctDescList :: [a] -> Set a

-- | &lt;math&gt;. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => Set a -> String

-- | &lt;math&gt;. The expression (<tt>showTreeWith hang wide map</tt>)
--   shows the tree that implements the set. If <tt>hang</tt> is
--   <tt>True</tt>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
--   
--   <pre>
--   Set&gt; putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]
--   4
--   +--2
--   |  +--1
--   |  +--3
--   +--5
--   
--   Set&gt; putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]
--   4
--   |
--   +--2
--   |  |
--   |  +--1
--   |  |
--   |  +--3
--   |
--   +--5
--   
--   Set&gt; putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]
--   +--5
--   |
--   4
--   |
--   |  +--3
--   |  |
--   +--2
--      |
--      +--1
--   </pre>
showTreeWith :: Show a => Bool -> Bool -> Set a -> String

-- | &lt;math&gt;. Test if the internal set structure is valid.
valid :: Ord a => Set a -> Bool
bin :: a -> Set a -> Set a -> Set a
balanced :: Set a -> Bool
link :: a -> Set a -> Set a -> Set a
merge :: Set a -> Set a -> Set a
instance (GHC.Internal.Data.Data.Data a, GHC.Internal.Classes.Ord a) => GHC.Internal.Data.Data.Data (Data.Set.Internal.Set a)
instance Data.Functor.Classes.Eq1 Data.Set.Internal.Set
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Set.Internal.Intersection a)
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Set.Internal.Set a)
instance GHC.Internal.Data.Foldable.Foldable Data.Set.Internal.Set
instance GHC.Internal.Classes.Ord a => GHC.Internal.IsList.IsList (Data.Set.Internal.Set a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Set.Internal.Set a)
instance GHC.Internal.Base.Monoid (Data.Set.Internal.MergeSet a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Base.Monoid (Data.Set.Internal.Set a)
instance Control.DeepSeq.NFData1 Data.Set.Internal.Set
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Set.Internal.Set a)
instance Data.Functor.Classes.Ord1 Data.Set.Internal.Set
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Set.Internal.Intersection a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Set.Internal.Set a)
instance (GHC.Internal.Read.Read a, GHC.Internal.Classes.Ord a) => GHC.Internal.Read.Read (Data.Set.Internal.Set a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Base.Semigroup (Data.Set.Internal.Intersection a)
instance GHC.Internal.Base.Semigroup (Data.Set.Internal.MergeSet a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Base.Semigroup (Data.Set.Internal.Set a)
instance Data.Functor.Classes.Show1 Data.Set.Internal.Set
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Set.Internal.Intersection a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Set.Internal.Set a)


-- | <h1>Finite Sets</h1>
--   
--   The <tt><a>Set</a> e</tt> type represents a set of elements of type
--   <tt>e</tt>. Most operations require that <tt>e</tt> be an instance of
--   the <a>Ord</a> class. A <a>Set</a> is strict in its elements.
--   
--   For a walkthrough of the most commonly used functions see the <a>sets
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.Set (Set)
--   import qualified Data.Set as Set
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two sets as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the entries in the first
--   argument to those in the second. Of course, this bias can only be
--   observed when equality is an equivalence relation instead of
--   structural equality.
--   
--   <h2>Warning</h2>
--   
--   The size of the set must not exceed <tt>maxBound::Int</tt>. Violation
--   of this condition is not detected and if the size limit is exceeded,
--   its behaviour is undefined.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Set</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   The time complexity is given for each operation in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the set.
--   
--   Operations like <a>member</a>, <a>insert</a>, and <a>delete</a> take
--   &lt;math&gt; time.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input sets respectively.
module Data.Set

-- | A set of values <tt>a</tt>.
data Set a

-- | &lt;math&gt;. The empty set.
empty :: Set a

-- | &lt;math&gt;. Create a singleton set.
singleton :: a -> Set a

-- | &lt;math&gt;. Create a set from a list of elements.
--   
--   If the elements are in non-decreasing order, this function takes
--   &lt;math&gt; time.
fromList :: Ord a => [a] -> Set a

-- | &lt;math&gt;. Build a set from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromAscList :: Eq a => [a] -> Set a

-- | &lt;math&gt;. Build a set from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDescList :: Eq a => [a] -> Set a

-- | &lt;math&gt;. Build a set from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctAscList :: [a] -> Set a

-- | &lt;math&gt;. Build a set from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctDescList :: [a] -> Set a

-- | &lt;math&gt;. Calculate the power set of a set: the set of all its
--   subsets.
--   
--   <pre>
--   t <a>`member`</a> powerSet s == t <a>`isSubsetOf`</a> s
--   </pre>
--   
--   Example:
--   
--   <pre>
--   powerSet (fromList [1,2,3]) =
--     fromList $ map fromList [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
--   </pre>
powerSet :: Set a -> Set (Set a)

-- | &lt;math&gt;. Insert an element in a set. If the set already contains
--   an element equal to the given value, it is replaced with the new
--   value.
insert :: Ord a => a -> Set a -> Set a

-- | &lt;math&gt;. Delete an element from a set.
delete :: Ord a => a -> Set a -> Set a

-- | &lt;math&gt; <tt>(<a>alterF</a> f x s)</tt> can delete or insert
--   <tt>x</tt> in <tt>s</tt> depending on whether an equal element is
--   found in <tt>s</tt>.
--   
--   In short:
--   
--   <pre>
--   <a>member</a> x &lt;$&gt; <a>alterF</a> f x s = f (<a>member</a> x s)
--   </pre>
--   
--   Note that unlike <a>insert</a>, <a>alterF</a> will <i>not</i> replace
--   an element equal to the given value.
--   
--   Note: <a>alterF</a> is a variant of the <tt>at</tt> combinator from
--   <a>Control.Lens.At</a>.
alterF :: (Ord a, Functor f) => (Bool -> f Bool) -> a -> Set a -> f (Set a)

-- | &lt;math&gt;. Is the element in the set?
member :: Ord a => a -> Set a -> Bool

-- | &lt;math&gt;. Is the element not in the set?
notMember :: Ord a => a -> Set a -> Bool

-- | &lt;math&gt;. Find largest element smaller than the given one.
--   
--   <pre>
--   lookupLT 3 (fromList [3, 5]) == Nothing
--   lookupLT 5 (fromList [3, 5]) == Just 3
--   </pre>
lookupLT :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find smallest element greater than the given one.
--   
--   <pre>
--   lookupGT 4 (fromList [3, 5]) == Just 5
--   lookupGT 5 (fromList [3, 5]) == Nothing
--   </pre>
lookupGT :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find largest element smaller or equal to the given one.
--   
--   <pre>
--   lookupLE 2 (fromList [3, 5]) == Nothing
--   lookupLE 4 (fromList [3, 5]) == Just 3
--   lookupLE 5 (fromList [3, 5]) == Just 5
--   </pre>
lookupLE :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Find smallest element greater or equal to the given one.
--   
--   <pre>
--   lookupGE 3 (fromList [3, 5]) == Just 3
--   lookupGE 4 (fromList [3, 5]) == Just 5
--   lookupGE 6 (fromList [3, 5]) == Nothing
--   </pre>
lookupGE :: Ord a => a -> Set a -> Maybe a

-- | &lt;math&gt;. Is this the empty set?
null :: Set a -> Bool

-- | &lt;math&gt;. The number of elements in the set.
size :: Set a -> Int

-- | &lt;math&gt;. <tt>(s1 `isSubsetOf` s2)</tt> indicates whether
--   <tt>s1</tt> is a subset of <tt>s2</tt>.
--   
--   <pre>
--   s1 `isSubsetOf` s2 = all (<a>`member`</a> s2) s1
--   s1 `isSubsetOf` s2 = null (s1 <a>`difference`</a> s2)
--   s1 `isSubsetOf` s2 = s1 <a>`union`</a> s2 == s2
--   s1 `isSubsetOf` s2 = s1 <a>`intersection`</a> s2 == s1
--   </pre>
isSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. <tt>(s1 `isProperSubsetOf` s2)</tt> indicates whether
--   <tt>s1</tt> is a proper subset of <tt>s2</tt>.
--   
--   <pre>
--   s1 `isProperSubsetOf` s2 = s1 <a>`isSubsetOf`</a> s2 &amp;&amp; s1 /= s2
--   </pre>
isProperSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. Check whether two sets are disjoint (i.e., their
--   intersection is empty).
--   
--   <pre>
--   disjoint (fromList [2,4,6])   (fromList [1,3])     == True
--   disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
--   disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
--   disjoint (fromList [])        (fromList [])        == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord a => Set a -> Set a -> Bool

-- | &lt;math&gt;. The union of two sets, preferring the first set when
--   equal elements are encountered.
union :: Ord a => Set a -> Set a -> Set a

-- | The union of the sets in a Foldable structure : (<tt><a>unions</a> ==
--   <a>foldl</a> <a>union</a> <a>empty</a></tt>).
unions :: (Foldable f, Ord a) => f (Set a) -> Set a

-- | &lt;math&gt;. Difference of two sets.
--   
--   Return elements of the first set not existing in the second set.
--   
--   <pre>
--   difference (fromList [5, 3]) (fromList [5, 7]) == singleton 3
--   </pre>
difference :: Ord a => Set a -> Set a -> Set a

-- | &lt;math&gt;. See <a>difference</a>.
(\\) :: Ord a => Set a -> Set a -> Set a
infixl 9 \\

-- | &lt;math&gt;. The intersection of two sets. Elements of the result
--   come from the first set, so for example
--   
--   <pre>
--   import qualified Data.Set as S
--   data AB = A | B deriving Show
--   instance Ord AB where compare _ _ = EQ
--   instance Eq AB where _ == _ = True
--   main = print (S.singleton A `S.intersection` S.singleton B,
--                 S.singleton B `S.intersection` S.singleton A)
--   </pre>
--   
--   prints <tt>(fromList [A],fromList [B])</tt>.
intersection :: Ord a => Set a -> Set a -> Set a

-- | The intersection of a series of sets. Intersections are performed
--   left-to-right.
intersections :: Ord a => NonEmpty (Set a) -> Set a

-- | &lt;math&gt;. The symmetric difference of two sets.
--   
--   The result contains elements that appear in exactly one of the two
--   sets.
--   
--   <pre>
--   symmetricDifference (fromList [0,2,4,6]) (fromList [0,3,6,9]) == fromList [2,3,4,9]
--   </pre>
symmetricDifference :: Ord a => Set a -> Set a -> Set a

-- | &lt;math&gt;. Calculate the Cartesian product of two sets.
--   
--   <pre>
--   cartesianProduct xs ys = fromList $ liftA2 (,) (toList xs) (toList ys)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   cartesianProduct (fromList [1,2]) (fromList ['a','b']) =
--     fromList [(1,'a'), (1,'b'), (2,'a'), (2,'b')]
--   </pre>
cartesianProduct :: Set a -> Set b -> Set (a, b)

-- | &lt;math&gt;. Calculate the disjoint union of two sets.
--   
--   <pre>
--   disjointUnion xs ys = map Left xs <a>`union`</a> map Right ys
--   </pre>
--   
--   Example:
--   
--   <pre>
--   disjointUnion (fromList [1,2]) (fromList ["hi", "bye"]) =
--     fromList [Left 1, Left 2, Right "hi", Right "bye"]
--   </pre>
disjointUnion :: Set a -> Set b -> Set (Either a b)

-- | <tt>Set</tt>s form a <a>Semigroup</a> under <a>intersection</a>.
newtype Intersection a
Intersection :: Set a -> Intersection a
[getIntersection] :: Intersection a -> Set a

-- | &lt;math&gt;. Filter all elements that satisfy the predicate.
filter :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Take while a predicate on the elements holds. The user
--   is responsible for ensuring that for all elements <tt>j</tt> and
--   <tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
--   note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
--   takeWhileAntitone p = <a>filter</a> p
--   </pre>
takeWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Drop while a predicate on the elements holds. The user
--   is responsible for ensuring that for all elements <tt>j</tt> and
--   <tt>k</tt> in the set, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See
--   note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
--   dropWhileAntitone p = <a>filter</a> (not . p)
--   </pre>
dropWhileAntitone :: (a -> Bool) -> Set a -> Set a

-- | &lt;math&gt;. Divide a set at the point where a predicate on the
--   elements stops holding. The user is responsible for ensuring that for
--   all elements <tt>j</tt> and <tt>k</tt> in the set, <tt>j &lt; k ==&gt;
--   p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partition p xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first element and to fail
--   after the last element).
spanAntitone :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. Partition the set into two sets, one with all elements
--   that satisfy the predicate and one with all elements that don't
--   satisfy the predicate. See also <a>split</a>.
partition :: (a -> Bool) -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. The expression (<tt><a>split</a> x set</tt>) is a pair
--   <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements of
--   <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
--   elements of <tt>set</tt> greater than <tt>x</tt>.
split :: Ord a => a -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot element was found in the original set.
splitMember :: Ord a => a -> Set a -> (Set a, Bool, Set a)

-- | &lt;math&gt;. Decompose a set into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a set in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first subset less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList [1..6]) ==
--     [fromList [1,2,3],fromList [4],fromList [5,6]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   subsets, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Set a -> [Set a]

-- | &lt;math&gt;. Look up the <i>index</i> of an element, which is its
--   zero-based index in the sorted sequence of elements. The index is a
--   number from <i>0</i> up to, but not including, the <a>size</a> of the
--   set.
--   
--   <pre>
--   isJust   (lookupIndex 2 (fromList [5,3])) == False
--   fromJust (lookupIndex 3 (fromList [5,3])) == 0
--   fromJust (lookupIndex 5 (fromList [5,3])) == 1
--   isJust   (lookupIndex 6 (fromList [5,3])) == False
--   </pre>
lookupIndex :: Ord a => a -> Set a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of an element, which is its
--   zero-based index in the sorted sequence of elements. The index is a
--   number from <i>0</i> up to, but not including, the <a>size</a> of the
--   set. Calls <a>error</a> when the element is not a <a>member</a> of the
--   set.
--   
--   <pre>
--   findIndex 2 (fromList [5,3])    Error: element is not in the set
--   findIndex 3 (fromList [5,3]) == 0
--   findIndex 5 (fromList [5,3]) == 1
--   findIndex 6 (fromList [5,3])    Error: element is not in the set
--   </pre>
findIndex :: Ord a => a -> Set a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sorted sequence of elements. If the
--   <i>index</i> is out of range (less than zero, greater or equal to
--   <a>size</a> of the set), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [5,3]) == 3
--   elemAt 1 (fromList [5,3]) == 5
--   elemAt 2 (fromList [5,3])    Error: index out of range
--   </pre>
elemAt :: Int -> Set a -> a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sorted sequence of elements. If the
--   <i>index</i> is out of range (less than zero, greater or equal to
--   <a>size</a> of the set), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0    (fromList [5,3]) == singleton 5
--   deleteAt 1    (fromList [5,3]) == singleton 3
--   deleteAt 2    (fromList [5,3])    Error: index out of range
--   deleteAt (-1) (fromList [5,3])    Error: index out of range
--   </pre>
deleteAt :: Int -> Set a -> Set a

-- | &lt;math&gt;. Take a given number of elements in order, beginning with
--   the smallest ones.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Set a -> Set a

-- | &lt;math&gt;. Drop a given number of elements in order, beginning with
--   the smallest ones.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Set a -> Set a

-- | &lt;math&gt;. Split a set at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Set a -> (Set a, Set a)

-- | &lt;math&gt;. <tt><a>map</a> f s</tt> is the set obtained by applying
--   <tt>f</tt> to each element of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   It's worth noting that the size of the result may be smaller if, for
--   some <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: Ord b => (a -> b) -> Set a -> Set b

-- | &lt;math&gt;. <tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but
--   works only when <tt>f</tt> is strictly increasing. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapMonotonic f s == map f s
--       where ls = toList s
--   </pre>
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>map</a> if the precondition may not hold.
mapMonotonic :: (a -> b) -> Set a -> Set b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toAscList set = foldr (:) [] set
--   </pre>
foldr :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toDescList set = foldl (flip (:)) [] set
--   </pre>
foldl :: (a -> b -> a) -> a -> Set b -> a

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Set b -> a

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator.

-- | <i>Deprecated: Use Data.Set.foldr instead</i>
fold :: (a -> b -> b) -> b -> Set a -> b

-- | &lt;math&gt;. The minimal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMin :: Set a -> Maybe a

-- | &lt;math&gt;. The maximal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMax :: Set a -> Maybe a

-- | &lt;math&gt;. The minimal element of the set. Calls <a>error</a> if
--   the set is empty.
findMin :: Set a -> a

-- | &lt;math&gt;. The maximal element of the set. Calls <a>error</a> if
--   the set is empty.
findMax :: Set a -> a

-- | &lt;math&gt;. Delete the minimal element. Returns an empty set if the
--   set is empty.
deleteMin :: Set a -> Set a

-- | &lt;math&gt;. Delete the maximal element. Returns an empty set if the
--   set is empty.
deleteMax :: Set a -> Set a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: Set a -> (a, Set a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: Set a -> (a, Set a)

-- | &lt;math&gt;. Retrieves the maximal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: Set a -> Maybe (a, Set a)

-- | &lt;math&gt;. Retrieves the minimal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: Set a -> Maybe (a, Set a)

-- | &lt;math&gt;. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: Set a -> [a]

-- | &lt;math&gt;. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: Set a -> [a]

-- | &lt;math&gt;. Convert the set to an ascending list of elements.
--   Subject to list fusion.
toAscList :: Set a -> [a]

-- | &lt;math&gt;. Convert the set to a descending list of elements.
--   Subject to list fusion.
toDescList :: Set a -> [a]

-- | &lt;math&gt;. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => Set a -> String

-- | &lt;math&gt;. The expression (<tt>showTreeWith hang wide map</tt>)
--   shows the tree that implements the set. If <tt>hang</tt> is
--   <tt>True</tt>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
--   
--   <pre>
--   Set&gt; putStrLn $ showTreeWith True False $ fromDistinctAscList [1..5]
--   4
--   +--2
--   |  +--1
--   |  +--3
--   +--5
--   
--   Set&gt; putStrLn $ showTreeWith True True $ fromDistinctAscList [1..5]
--   4
--   |
--   +--2
--   |  |
--   |  +--1
--   |  |
--   |  +--3
--   |
--   +--5
--   
--   Set&gt; putStrLn $ showTreeWith False True $ fromDistinctAscList [1..5]
--   +--5
--   |
--   4
--   |
--   |  +--3
--   |  |
--   +--2
--      |
--      +--1
--   </pre>
showTreeWith :: Show a => Bool -> Bool -> Set a -> String

-- | &lt;math&gt;. Test if the internal set structure is valid.
valid :: Ord a => Set a -> Bool


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite sequences (internals)</h1>
--   
--   The <tt><a>Seq</a> a</tt> type represents a finite sequence of values
--   of type <tt>a</tt>.
--   
--   <h2>Implementation</h2>
--   
--   The implementation uses 2-3 finger trees annotated with sizes, as
--   described in section 4.2 of
--   
--   <ul>
--   <li>Ralf Hinze and Ross Paterson, "<i>Finger trees: a simple
--   general-purpose data structure</i>", Journal of Functional Programming
--   16:2 (2006) pp 197-217.
--   <a>http://staff.city.ac.uk/~ross/papers/FingerTree.html</a>.</li>
--   </ul>
module Data.Sequence.Internal
newtype Elem a
Elem :: a -> Elem a
[getElem] :: Elem a -> a
data FingerTree a
EmptyT :: FingerTree a
Single :: a -> FingerTree a
Deep :: Int -> Digit a -> FingerTree (Node a) -> Digit a -> FingerTree a
data Node a
Node2 :: Int -> a -> a -> Node a
Node3 :: Int -> a -> a -> a -> Node a
data Digit a
One :: a -> Digit a
Two :: a -> a -> Digit a
Three :: a -> a -> a -> Digit a
Four :: a -> a -> a -> a -> Digit a
class Sized a
size :: Sized a => a -> Int
class MaybeForce a

-- | General-purpose finite sequences.
newtype Seq a
Seq :: FingerTree (Elem a) -> Seq a

-- | A bidirectional pattern synonym matching an empty sequence.
pattern Empty :: Seq a

-- | A bidirectional pattern synonym viewing the front of a non-empty
--   sequence.
pattern (:<|) :: a -> Seq a -> Seq a

-- | A bidirectional pattern synonym viewing the rear of a non-empty
--   sequence.
pattern (:|>) :: Seq a -> a -> Seq a
infixl 5 :|>
infixr 5 :<|
foldDigit :: (b -> b -> b) -> (a -> b) -> Digit a -> b
foldNode :: (b -> b -> b) -> (a -> b) -> Node a -> b
foldWithIndexDigit :: Sized a => (b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
foldWithIndexNode :: Sized a => (m -> m -> m) -> (Int -> a -> m) -> Int -> Node a -> m

-- | &lt;math&gt;. The empty sequence.
empty :: Seq a

-- | &lt;math&gt;. A singleton sequence.
singleton :: a -> Seq a

-- | &lt;math&gt;. Add an element to the left end of a sequence. Mnemonic:
--   a triangle with the single element at the pointy end.
(<|) :: a -> Seq a -> Seq a
infixr 5 <|

-- | &lt;math&gt;. Add an element to the right end of a sequence. Mnemonic:
--   a triangle with the single element at the pointy end.
(|>) :: Seq a -> a -> Seq a
infixl 5 |>

-- | &lt;math&gt;. Concatenate two sequences.
(><) :: Seq a -> Seq a -> Seq a
infixr 5 ><

-- | &lt;math&gt;. Create a sequence from a finite list of elements. There
--   is a function <a>toList</a> in the opposite direction for all
--   instances of the <a>Foldable</a> class, including <a>Seq</a>.
fromList :: [a] -> Seq a

-- | &lt;math&gt;. Convert a given sequence length and a function
--   representing that sequence into a sequence.
fromFunction :: Int -> (Int -> a) -> Seq a

-- | &lt;math&gt;. Create a sequence consisting of the elements of an
--   <a>Array</a>. Note that the resulting sequence elements may be
--   evaluated lazily (as on GHC), so you must force the entire structure
--   to be sure that the original array can be garbage-collected.
fromArray :: Ix i => Array i a -> Seq a

-- | &lt;math&gt;. <tt>replicate n x</tt> is a sequence consisting of
--   <tt>n</tt> copies of <tt>x</tt>.
replicate :: Int -> a -> Seq a

-- | <a>replicateA</a> is an <a>Applicative</a> version of
--   <a>replicate</a>, and makes &lt;math&gt; calls to <a>liftA2</a> and
--   <a>pure</a>.
--   
--   <pre>
--   replicateA n x = sequenceA (replicate n x)
--   </pre>
replicateA :: Applicative f => Int -> f a -> f (Seq a)

-- | <a>replicateM</a> is the <tt>Seq</tt> counterpart of
--   <tt>Control.Monad.<a>replicateM</a></tt>.
--   
--   <pre>
--   replicateM n x = sequence (replicate n x)
--   </pre>
--   
--   For <tt>base &gt;= 4.8.0</tt> and <tt>containers &gt;= 0.5.11</tt>,
--   <a>replicateM</a> is a synonym for <a>replicateA</a>.
replicateM :: Applicative m => Int -> m a -> m (Seq a)

-- | &lt;math&gt;. <tt><a>cycleTaking</a> k xs</tt> forms a sequence of
--   length <tt>k</tt> by repeatedly concatenating <tt>xs</tt> with itself.
--   <tt>xs</tt> may only be empty if <tt>k</tt> is 0.
--   
--   <pre>
--   cycleTaking k = fromList . take k . cycle . toList
--   </pre>
cycleTaking :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Constructs a sequence by repeated application of a
--   function to a seed value.
--   
--   <pre>
--   iterateN n f x = fromList (Prelude.take n (Prelude.iterate f x))
--   </pre>
iterateN :: Int -> (a -> a) -> a -> Seq a

-- | Builds a sequence from a seed value. Takes time linear in the number
--   of generated elements. <i>WARNING:</i> If the number of generated
--   elements is infinite, this method will not terminate.
unfoldr :: (b -> Maybe (a, b)) -> b -> Seq a

-- | <tt><a>unfoldl</a> f x</tt> is equivalent to <tt><a>reverse</a>
--   (<a>unfoldr</a> (<a>fmap</a> swap . f) x)</tt>.
unfoldl :: (b -> Maybe (b, a)) -> b -> Seq a

-- | &lt;math&gt;. Is this the empty sequence?
null :: Seq a -> Bool

-- | &lt;math&gt;. The number of elements in the sequence.
length :: Seq a -> Int

-- | View of the left end of a sequence.
data ViewL a

-- | empty sequence
EmptyL :: ViewL a

-- | leftmost element and the rest of the sequence
(:<) :: a -> Seq a -> ViewL a
infixr 5 :<

-- | &lt;math&gt;. Analyse the left end of a sequence.
viewl :: Seq a -> ViewL a

-- | View of the right end of a sequence.
data ViewR a

-- | empty sequence
EmptyR :: ViewR a

-- | the sequence minus the rightmost element, and the rightmost element
(:>) :: Seq a -> a -> ViewR a
infixl 5 :>

-- | &lt;math&gt;. Analyse the right end of a sequence.
viewr :: Seq a -> ViewR a

-- | <a>scanl</a> is similar to <a>foldl</a>, but returns a sequence of
--   reduced values from the left:
--   
--   <pre>
--   scanl f z (fromList [x1, x2, ...]) = fromList [z, z `f` x1, (z `f` x1) `f` x2, ...]
--   </pre>
scanl :: (a -> b -> a) -> a -> Seq b -> Seq a

-- | <a>scanl1</a> is a variant of <a>scanl</a> that has no starting value
--   argument:
--   
--   <pre>
--   scanl1 f (fromList [x1, x2, ...]) = fromList [x1, x1 `f` x2, ...]
--   </pre>
scanl1 :: (a -> a -> a) -> Seq a -> Seq a

-- | <a>scanr</a> is the right-to-left dual of <a>scanl</a>.
scanr :: (a -> b -> b) -> b -> Seq a -> Seq b

-- | <a>scanr1</a> is a variant of <a>scanr</a> that has no starting value
--   argument.
scanr1 :: (a -> a -> a) -> Seq a -> Seq a

-- | &lt;math&gt;. Returns a sequence of all suffixes of this sequence,
--   longest first. For example,
--   
--   <pre>
--   tails (fromList "abc") = fromList [fromList "abc", fromList "bc", fromList "c", fromList ""]
--   </pre>
--   
--   Evaluating the &lt;math&gt;th suffix takes &lt;math&gt;, but
--   evaluating every suffix in the sequence takes &lt;math&gt; due to
--   sharing.
tails :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. Returns a sequence of all prefixes of this sequence,
--   shortest first. For example,
--   
--   <pre>
--   inits (fromList "abc") = fromList [fromList "", fromList "a", fromList "ab", fromList "abc"]
--   </pre>
--   
--   Evaluating the &lt;math&gt;th prefix takes &lt;math&gt;, but
--   evaluating every prefix in the sequence takes &lt;math&gt; due to
--   sharing.
inits :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. <tt>chunksOf c xs</tt> splits <tt>xs</tt> into chunks of
--   size <tt>c&gt;0</tt>. If <tt>c</tt> does not divide the length of
--   <tt>xs</tt> evenly, then the last element of the result will be short.
--   
--   Side note: the given performance bound is missing some messy terms
--   that only really affect edge cases. Performance degrades smoothly from
--   &lt;math&gt; (for &lt;math&gt;) to &lt;math&gt; (for &lt;math&gt;).
--   The true bound is more like &lt;math&gt;
chunksOf :: Int -> Seq a -> Seq (Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
--   <a>takeWhileL</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns the longest prefix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt>.
takeWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
--   <a>takeWhileR</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns the longest suffix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt>.
--   
--   <tt><a>takeWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
--   (<a>takeWhileL</a> p (<a>reverse</a> xs))</tt>.
takeWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
--   <tt><a>dropWhileL</a> p xs</tt> returns the suffix remaining after
--   <tt><a>takeWhileL</a> p xs</tt>.
dropWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
--   <tt><a>dropWhileR</a> p xs</tt> returns the prefix remaining after
--   <tt><a>takeWhileR</a> p xs</tt>.
--   
--   <tt><a>dropWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
--   (<a>dropWhileL</a> p (<a>reverse</a> xs))</tt>.
dropWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length. <a>spanl</a>,
--   applied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
--   a pair whose first element is the longest prefix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt> and the second element
--   is the remainder of the sequence.
spanl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the suffix length. <a>spanr</a>,
--   applied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
--   a pair whose <i>first</i> element is the longest <i>suffix</i>
--   (possibly empty) of <tt>xs</tt> of elements that satisfy <tt>p</tt>
--   and the second element is the remainder of the sequence.
spanr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the breakpoint index.
--   <a>breakl</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns a pair whose first element is the longest prefix
--   (possibly empty) of <tt>xs</tt> of elements that <i>do not satisfy</i>
--   <tt>p</tt> and the second element is the remainder of the sequence.
--   
--   <tt><a>breakl</a> p</tt> is equivalent to <tt><a>spanl</a> (not .
--   p)</tt>.
breakl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | <tt><a>breakr</a> p</tt> is equivalent to <tt><a>spanr</a> (not .
--   p)</tt>.
breakr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>partition</a> function takes a predicate
--   <tt>p</tt> and a sequence <tt>xs</tt> and returns sequences of those
--   elements which do and do not satisfy the predicate.
partition :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>filter</a> function takes a predicate <tt>p</tt>
--   and a sequence <tt>xs</tt> and returns a sequence of those elements
--   which satisfy the predicate.
filter :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
--   If the specified position is negative or at least the length of the
--   sequence, <a>lookup</a> returns <a>Nothing</a>.
--   
--   <pre>
--   0 &lt;= i &lt; length xs ==&gt; lookup i xs == Just (toList xs !! i)
--   </pre>
--   
--   <pre>
--   i &lt; 0 || i &gt;= length xs ==&gt; lookup i xs = Nothing
--   </pre>
--   
--   Unlike <a>index</a>, this can be used to retrieve an element without
--   forcing it. For example, to insert the fifth element of a sequence
--   <tt>xs</tt> into a <a>Map</a> <tt>m</tt> at key <tt>k</tt>, you could
--   use
--   
--   <pre>
--   case lookup 5 xs of
--     Nothing -&gt; m
--     Just x -&gt; <a>insert</a> k x m
--   </pre>
lookup :: Int -> Seq a -> Maybe a

-- | &lt;math&gt;. A flipped, infix version of <a>lookup</a>.
(!?) :: Seq a -> Int -> Maybe a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
--   The argument should thus be a non-negative integer less than the size
--   of the sequence. If the position is out of range, <a>index</a> fails
--   with an error.
--   
--   <pre>
--   xs `index` i = toList xs !! i
--   </pre>
--   
--   Caution: <a>index</a> necessarily delays retrieving the requested
--   element until the result is forced. It can therefore lead to a space
--   leak if the result is stored, unforced, in another structure. To
--   retrieve an element immediately without forcing it, use <a>lookup</a>
--   or <a>(!?)</a>.
index :: Seq a -> Int -> a

-- | &lt;math&gt;. Update the element at the specified position. If the
--   position is out of range, the original sequence is returned.
--   <a>adjust</a> can lead to poor performance and even memory leaks,
--   because it does not force the new value before installing it in the
--   sequence. <a>adjust'</a> should usually be preferred.
adjust :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Update the element at the specified position. If the
--   position is out of range, the original sequence is returned. The new
--   value is forced before it is installed in the sequence.
--   
--   <pre>
--   adjust' f i xs =
--    case xs !? i of
--      Nothing -&gt; xs
--      Just x -&gt; let !x' = f x
--                in update i x' xs
--   </pre>
adjust' :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Replace the element at the specified position. If the
--   position is out of range, the original sequence is returned.
update :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. The first <tt>i</tt> elements of a sequence. If
--   <tt>i</tt> is negative, <tt><a>take</a> i s</tt> yields the empty
--   sequence. If the sequence contains fewer than <tt>i</tt> elements, the
--   whole sequence is returned.
take :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Elements of a sequence after the first <tt>i</tt>. If
--   <tt>i</tt> is negative, <tt><a>drop</a> i s</tt> yields the whole
--   sequence. If the sequence contains fewer than <tt>i</tt> elements, the
--   empty sequence is returned.
drop :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. <tt><a>insertAt</a> i x xs</tt> inserts <tt>x</tt> into
--   <tt>xs</tt> at the index <tt>i</tt>, shifting the rest of the sequence
--   over.
--   
--   <pre>
--   insertAt 2 x (fromList [a,b,c,d]) = fromList [a,b,x,c,d]
--   insertAt 4 x (fromList [a,b,c,d]) = insertAt 10 x (fromList [a,b,c,d])
--                                     = fromList [a,b,c,d,x]
--   </pre>
--   
--   <pre>
--   insertAt i x xs = take i xs &gt;&lt; singleton x &gt;&lt; drop i xs
--   </pre>
insertAt :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. Delete the element of a sequence at a given index.
--   Return the original sequence if the index is out of range.
--   
--   <pre>
--   deleteAt 2 [a,b,c,d] = [a,b,d]
--   deleteAt 4 [a,b,c,d] = deleteAt (-1) [a,b,c,d] = [a,b,c,d]
--   </pre>
deleteAt :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Split a sequence at a given position. <tt><a>splitAt</a>
--   i s = (<a>take</a> i s, <a>drop</a> i s)</tt>.
splitAt :: Int -> Seq a -> (Seq a, Seq a)

-- | <a>elemIndexL</a> finds the leftmost index of the specified element,
--   if it is present, and otherwise <a>Nothing</a>.
elemIndexL :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesL</a> finds the indices of the specified element, from
--   left to right (i.e. in ascending order).
elemIndicesL :: Eq a => a -> Seq a -> [Int]

-- | <a>elemIndexR</a> finds the rightmost index of the specified element,
--   if it is present, and otherwise <a>Nothing</a>.
elemIndexR :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesR</a> finds the indices of the specified element, from
--   right to left (i.e. in descending order).
elemIndicesR :: Eq a => a -> Seq a -> [Int]

-- | <tt><a>findIndexL</a> p xs</tt> finds the index of the leftmost
--   element that satisfies <tt>p</tt>, if any exist.
findIndexL :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesL</a> p</tt> finds all indices of elements that
--   satisfy <tt>p</tt>, in ascending order.
findIndicesL :: (a -> Bool) -> Seq a -> [Int]

-- | <tt><a>findIndexR</a> p xs</tt> finds the index of the rightmost
--   element that satisfies <tt>p</tt>, if any exist.
findIndexR :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesR</a> p</tt> finds all indices of elements that
--   satisfy <tt>p</tt>, in descending order.
findIndicesR :: (a -> Bool) -> Seq a -> [Int]
foldMapWithIndex :: Monoid m => (Int -> a -> m) -> Seq a -> m

-- | <a>foldlWithIndex</a> is a version of <a>foldl</a> that also provides
--   access to the index of each element.
foldlWithIndex :: (b -> Int -> a -> b) -> b -> Seq a -> b

-- | <a>foldrWithIndex</a> is a version of <a>foldr</a> that also provides
--   access to the index of each element.
foldrWithIndex :: (Int -> a -> b -> b) -> b -> Seq a -> b

-- | A generalization of <a>fmap</a>, <a>mapWithIndex</a> takes a mapping
--   function that also depends on the element's index, and applies it to
--   every element in the sequence.
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b

-- | <a>traverseWithIndex</a> is a version of <a>traverse</a> that also
--   offers access to the index of each element.
traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)

-- | &lt;math&gt;. The reverse of a sequence.
reverse :: Seq a -> Seq a

-- | &lt;math&gt;. Intersperse an element between the elements of a
--   sequence.
--   
--   <pre>
--   intersperse a empty = empty
--   intersperse a (singleton x) = singleton x
--   intersperse a (fromList [x,y]) = fromList [x,a,y]
--   intersperse a (fromList [x,y,z]) = fromList [x,a,y,a,z]
--   </pre>
intersperse :: a -> Seq a -> Seq a
liftA2Seq :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip</a> takes two sequences and returns a sequence of
--   corresponding pairs. If one input is short, excess elements are
--   discarded from the right end of the longer sequence.
zip :: Seq a -> Seq b -> Seq (a, b)

-- | &lt;math&gt;. <a>zipWith</a> generalizes <a>zip</a> by zipping with
--   the function given as the first argument, instead of a tupling
--   function. For example, <tt>zipWith (+)</tt> is applied to two
--   sequences to take the sequence of corresponding sums.
zipWith :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip3</a> takes three sequences and returns a sequence
--   of triples, analogous to <a>zip</a>.
zip3 :: Seq a -> Seq b -> Seq c -> Seq (a, b, c)

-- | &lt;math&gt;. <a>zipWith3</a> takes a function which combines three
--   elements, as well as three sequences and returns a sequence of their
--   point-wise combinations, analogous to <a>zipWith</a>.
zipWith3 :: (a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d

-- | &lt;math&gt;. <a>zip4</a> takes four sequences and returns a sequence
--   of quadruples, analogous to <a>zip</a>.
zip4 :: Seq a -> Seq b -> Seq c -> Seq d -> Seq (a, b, c, d)

-- | &lt;math&gt;. <a>zipWith4</a> takes a function which combines four
--   elements, as well as four sequences and returns a sequence of their
--   point-wise combinations, analogous to <a>zipWith</a>.
zipWith4 :: (a -> b -> c -> d -> e) -> Seq a -> Seq b -> Seq c -> Seq d -> Seq e

-- | Unzip a sequence of pairs.
--   
--   <pre>
--   unzip ps = ps <a>`seq`</a> (<a>fmap</a> <a>fst</a> ps) (<a>fmap</a> <a>snd</a> ps)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   unzip $ fromList [(1,"a"), (2,"b"), (3,"c")] =
--     (fromList [1,2,3], fromList ["a", "b", "c"])
--   </pre>
--   
--   See the note about efficiency at <a>unzipWith</a>.
unzip :: Seq (a, b) -> (Seq a, Seq b)

-- | &lt;math&gt;. Unzip a sequence using a function to divide elements.
--   
--   <pre>
--   unzipWith f xs == <a>unzip</a> (<a>fmap</a> f xs)
--   </pre>
--   
--   Efficiency note:
--   
--   <tt>unzipWith</tt> produces its two results in lockstep. If you
--   calculate <tt> unzipWith f xs </tt> and fully force <i>either</i> of
--   the results, then the entire structure of the <i>other</i> one will be
--   built as well. This behavior allows the garbage collector to collect
--   each calculated pair component as soon as it dies, without having to
--   wait for its mate to die. If you do not need this behavior, you may be
--   better off simply calculating the sequence of pairs and using
--   <a>fmap</a> to extract each component sequence.
unzipWith :: (a -> (b, c)) -> Seq a -> (Seq b, Seq c)
instance GHC.Internal.Base.Alternative Data.Sequence.Internal.Seq
instance GHC.Internal.Base.Applicative Data.Sequence.Internal.Seq
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Sequence.Internal.Seq a)
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Sequence.Internal.ViewR a)
instance Data.Functor.Classes.Eq1 Data.Sequence.Internal.Seq
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Sequence.Internal.Seq a)
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Sequence.Internal.ViewR a)
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.Digit
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.Elem
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.FingerTree
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.Node
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.Seq
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.ViewL
instance GHC.Internal.Data.Foldable.Foldable Data.Sequence.Internal.ViewR
instance GHC.Internal.Base.Functor Data.Sequence.Internal.Digit
instance GHC.Internal.Base.Functor Data.Sequence.Internal.Elem
instance GHC.Internal.Base.Functor Data.Sequence.Internal.FingerTree
instance GHC.Internal.Base.Functor Data.Sequence.Internal.Node
instance GHC.Internal.Base.Functor Data.Sequence.Internal.Seq
instance GHC.Internal.Base.Functor Data.Sequence.Internal.ViewL
instance GHC.Internal.Base.Functor Data.Sequence.Internal.ViewR
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.Digit
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.Elem
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.FingerTree
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.Node
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.ViewL
instance GHC.Internal.Generics.Generic1 Data.Sequence.Internal.ViewR
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.Digit a)
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.Elem a)
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.FingerTree a)
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.Node a)
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Generics.Generic (Data.Sequence.Internal.ViewR a)
instance GHC.Internal.IsList.IsList (Data.Sequence.Internal.Seq a)
instance (a GHC.Internal.Types.~ GHC.Internal.Types.Char) => GHC.Internal.Data.String.IsString (Data.Sequence.Internal.Seq a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.Digit a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.FingerTree a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.Node a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.Seq a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Sequence.Internal.ViewR a)
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.Elem a)
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.ForceBox a)
instance Data.Sequence.Internal.MaybeForce (Data.Sequence.Internal.Node a)
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Sequence.Internal.Seq
instance GHC.Internal.Base.MonadPlus Data.Sequence.Internal.Seq
instance GHC.Internal.Base.Monad Data.Sequence.Internal.Seq
instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Sequence.Internal.Seq
instance GHC.Internal.Base.Monoid (Data.Sequence.Internal.Seq a)
instance Control.DeepSeq.NFData1 Data.Sequence.Internal.Digit
instance Control.DeepSeq.NFData1 Data.Sequence.Internal.Elem
instance Control.DeepSeq.NFData1 Data.Sequence.Internal.FingerTree
instance Control.DeepSeq.NFData1 Data.Sequence.Internal.Node
instance Control.DeepSeq.NFData1 Data.Sequence.Internal.Seq
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Digit a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Elem a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.FingerTree a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Node a)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Internal.Seq a)
instance Data.Functor.Classes.Ord1 Data.Sequence.Internal.Seq
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Sequence.Internal.Seq a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Sequence.Internal.ViewR a)
instance Data.Functor.Classes.Read1 Data.Sequence.Internal.Seq
instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Sequence.Internal.Seq a)
instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Sequence.Internal.ViewR a)
instance GHC.Internal.Base.Semigroup (Data.Sequence.Internal.Seq a)
instance Data.Functor.Classes.Show1 Data.Sequence.Internal.Seq
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Sequence.Internal.Seq a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Sequence.Internal.ViewL a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Sequence.Internal.ViewR a)
instance Data.Sequence.Internal.Sized a => Data.Sequence.Internal.Sized (Data.Sequence.Internal.Digit a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.Elem a)
instance Data.Sequence.Internal.Sized a => Data.Sequence.Internal.Sized (Data.Sequence.Internal.FingerTree a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.ForceBox a)
instance Data.Sequence.Internal.Sized (Data.Sequence.Internal.Node a)
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.Digit
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.Elem
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.FingerTree
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.Node
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.Seq
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.ViewL
instance GHC.Internal.Data.Traversable.Traversable Data.Sequence.Internal.ViewR
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Digit
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Elem
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.FingerTree
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Node
instance Data.Sequence.Internal.UnzipWith Data.Sequence.Internal.Seq


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Description</h1>
--   
--   This module provides the various sorting implementations for
--   <a>Data.Sequence</a>. Further notes are available in the file
--   sorting.md (in this directory).
module Data.Sequence.Internal.Sorting

-- | &lt;math&gt;. <a>sort</a> sorts the specified <a>Seq</a> by the
--   natural ordering of its elements. The sort is stable, meaning the
--   order of equal elements is preserved. If stability is not required,
--   <a>unstableSort</a> can be slightly faster.
sort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. <a>sortBy</a> sorts the specified <a>Seq</a> according
--   to the specified comparator. The sort is stable, meaning the order of
--   equal elements is preserved. If stability is not required,
--   <a>unstableSortBy</a> can be slightly faster.
sortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sortOn</a> sorts the specified <a>Seq</a> by
--   comparing the results of a key function applied to each element. The
--   sort is stable, meaning the order of equal elements is preserved.
--   <tt><a>sortOn</a> f</tt> is equivalent to <tt><a>sortBy</a>
--   (<a>compare</a> <a>`on`</a> f)</tt>, but has the performance advantage
--   of only evaluating <tt>f</tt> once for each element in the input
--   <a>Seq</a>.
--   
--   An example of using <a>sortOn</a> might be to sort a <a>Seq</a> of
--   strings according to their length:
--   
--   <pre>
--   sortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
--   </pre>
--   
--   If, instead, <a>sortBy</a> had been used, <a>length</a> would be
--   evaluated on every comparison, giving &lt;math&gt; evaluations, rather
--   than &lt;math&gt;.
--   
--   If <tt>f</tt> is very cheap (for example a record selector, or
--   <a>fst</a>), <tt><a>sortBy</a> (<a>compare</a> <a>`on`</a> f)</tt>
--   will be faster than <tt><a>sortOn</a> f</tt>.
sortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSort</a> sorts the specified <a>Seq</a> by
--   the natural ordering of its elements, but the sort is not stable. This
--   algorithm is frequently faster and uses less memory than <a>sort</a>.
unstableSort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. A generalization of <a>unstableSort</a>,
--   <a>unstableSortBy</a> takes an arbitrary comparator and sorts the
--   specified sequence. The sort is not stable. This algorithm is
--   frequently faster and uses less memory than <a>sortBy</a>.
unstableSortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSortOn</a> sorts the specified <a>Seq</a> by
--   comparing the results of a key function applied to each element.
--   <tt><a>unstableSortOn</a> f</tt> is equivalent to
--   <tt><a>unstableSortBy</a> (<a>compare</a> <a>`on`</a> f)</tt>, but has
--   the performance advantage of only evaluating <tt>f</tt> once for each
--   element in the input <a>Seq</a>.
--   
--   An example of using <a>unstableSortOn</a> might be to sort a
--   <a>Seq</a> of strings according to their length:
--   
--   <pre>
--   unstableSortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
--   </pre>
--   
--   If, instead, <a>unstableSortBy</a> had been used, <a>length</a> would
--   be evaluated on every comparison, giving &lt;math&gt; evaluations,
--   rather than &lt;math&gt;.
--   
--   If <tt>f</tt> is very cheap (for example a record selector, or
--   <a>fst</a>), <tt><a>unstableSortBy</a> (<a>compare</a> <a>`on`</a>
--   f)</tt> will be faster than <tt><a>unstableSortOn</a> f</tt>.
unstableSortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | A simple pairing heap.
data Queue e
Q :: e -> QList e -> Queue e
data QList e
Nil :: QList e
QCons :: Queue e -> QList e -> QList e
infixr 8 `QCons`

-- | A pairing heap tagged with the original position of elements, to allow
--   for stable sorting.
data IndexedQueue e
IQ :: Int -> e -> IQList e -> IndexedQueue e
data IQList e
IQNil :: IQList e
IQCons :: IndexedQueue e -> IQList e -> IQList e
infixr 8 `IQCons`

-- | A pairing heap tagged with some key for sorting elements, for use in
--   <a>unstableSortOn</a>.
data TaggedQueue a b
TQ :: a -> b -> TQList a b -> TaggedQueue a b
data TQList a b
TQNil :: TQList a b
TQCons :: TaggedQueue a b -> TQList a b -> TQList a b
infixr 8 `TQCons`

-- | A pairing heap tagged with both a key and the original position of its
--   elements, for use in <a>sortOn</a>.
data IndexedTaggedQueue e a
ITQ :: Int -> e -> a -> ITQList e a -> IndexedTaggedQueue e a
data ITQList e a
ITQNil :: ITQList e a
ITQCons :: IndexedTaggedQueue e a -> ITQList e a -> ITQList e a
infixr 8 `ITQCons`

-- | <a>mergeQ</a> merges two <a>Queue</a>s.
mergeQ :: (a -> a -> Ordering) -> Queue a -> Queue a -> Queue a

-- | <a>mergeIQ</a> merges two <a>IndexedQueue</a>s, taking into account
--   the original position of the elements.
mergeIQ :: (a -> a -> Ordering) -> IndexedQueue a -> IndexedQueue a -> IndexedQueue a

-- | <a>mergeTQ</a> merges two <a>TaggedQueue</a>s, based on the tag value.
mergeTQ :: (a -> a -> Ordering) -> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b

-- | <a>mergeITQ</a> merges two <a>IndexedTaggedQueue</a>s, based on the
--   tag value, taking into account the original position of the elements.
mergeITQ :: (a -> a -> Ordering) -> IndexedTaggedQueue a b -> IndexedTaggedQueue a b -> IndexedTaggedQueue a b

-- | Pop the smallest element from the queue, using the supplied
--   comparator.
popMinQ :: (e -> e -> Ordering) -> Queue e -> (Queue e, e)

-- | Pop the smallest element from the queue, using the supplied
--   comparator, deferring to the item's original position when the
--   comparator returns <a>EQ</a>.
popMinIQ :: (e -> e -> Ordering) -> IndexedQueue e -> (IndexedQueue e, e)

-- | Pop the smallest element from the queue, using the supplied comparator
--   on the tag.
popMinTQ :: (a -> a -> Ordering) -> TaggedQueue a b -> (TaggedQueue a b, b)

-- | Pop the smallest element from the queue, using the supplied comparator
--   on the tag, deferring to the item's original position when the
--   comparator returns <a>EQ</a>.
popMinITQ :: (e -> e -> Ordering) -> IndexedTaggedQueue e b -> (IndexedTaggedQueue e b, b)
buildQ :: (b -> b -> Ordering) -> (a -> Queue b) -> FingerTree a -> Maybe (Queue b)
buildIQ :: (b -> b -> Ordering) -> (Int -> Elem y -> IndexedQueue b) -> Int -> FingerTree (Elem y) -> Maybe (IndexedQueue b)
buildTQ :: (b -> b -> Ordering) -> (a -> TaggedQueue b c) -> FingerTree a -> Maybe (TaggedQueue b c)
buildITQ :: (b -> b -> Ordering) -> (Int -> Elem y -> IndexedTaggedQueue b c) -> Int -> FingerTree (Elem y) -> Maybe (IndexedTaggedQueue b c)

-- | A <a>foldMap</a>-like function, specialized to the <a>Option</a>
--   monoid, which takes advantage of the internal structure of <a>Seq</a>
--   to avoid wrapping in <a>Maybe</a> at certain points.
foldToMaybeTree :: (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b

-- | A <a>foldMapWithIndex</a>-like function, specialized to the
--   <a>Option</a> monoid, which takes advantage of the internal structure
--   of <a>Seq</a> to avoid wrapping in <a>Maybe</a> at certain points.
foldToMaybeWithIndexTree :: (b -> b -> b) -> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b


-- | <h1>Finite sequences</h1>
--   
--   The <tt><a>Seq</a> a</tt> type represents a finite sequence of values
--   of type <tt>a</tt>.
--   
--   Sequences generally behave very much like lists.
--   
--   <ul>
--   <li>The class instances for sequences are all based very closely on
--   those for lists.</li>
--   <li>Many functions in this module have the same names as functions in
--   the <a>Prelude</a> or in <a>Data.List</a>. In almost all cases, these
--   functions behave analogously. For example, <a>filter</a> filters a
--   sequence in exactly the same way that
--   <tt><a>Prelude</a>.<a>filter</a></tt> filters a list. The only major
--   exception is the <a>lookup</a> function, which is based on the
--   function by that name in <a>Data.IntMap</a> rather than the one in
--   <a>Prelude</a>.</li>
--   </ul>
--   
--   There are two major differences between sequences and lists:
--   
--   <ul>
--   <li>Sequences support a wider variety of efficient operations than do
--   lists. Notably, they offer<ul><li>Constant-time access to both the
--   front and the rear with <a>&lt;|</a>, <a>|&gt;</a>, <a>viewl</a>,
--   <a>viewr</a>. For recent GHC versions, this can be done more
--   conveniently using the bidirectional patterns <a>Empty</a>,
--   <a>:&lt;|</a>, and <a>:|&gt;</a>. See the detailed explanation in the
--   "Pattern synonyms" section.</li><li>Logarithmic-time concatenation
--   with <a>&gt;&lt;</a></li><li>Logarithmic-time splitting with
--   <a>splitAt</a>, <a>take</a> and <a>drop</a></li><li>Logarithmic-time
--   access to any element with <a>lookup</a>, <a>!?</a>, <a>index</a>,
--   <a>insertAt</a>, <a>deleteAt</a>, <a>adjust'</a>, and
--   <a>update</a></li></ul></li>
--   </ul>
--   
--   Note that sequences are typically <i>slower</i> than lists when using
--   only operations for which they have the same big-&lt;math&gt;
--   complexity: sequences make rather mediocre stacks!
--   
--   <ul>
--   <li>Whereas lists can be either finite or infinite, sequences are
--   always finite. As a result, a sequence is strict in its length.
--   Ignoring efficiency, you can imagine that <a>Seq</a> is defined<pre>
--   data Seq a = Empty | a :&lt;| !(Seq a)</pre>This means that many
--   operations on sequences are stricter than those on lists. For
--   example,<pre> (1 : undefined) !! 0 = 1</pre>but<pre> (1 :&lt;|
--   undefined) <a>`index`</a> 0 = undefined</pre></li>
--   </ul>
--   
--   Sequences may also be compared to immutable <a>arrays</a> or
--   <a>vectors</a>. Like these structures, sequences support fast
--   indexing, although not as fast. But editing an immutable array or
--   vector, or combining it with another, generally requires copying the
--   entire structure; sequences generally avoid that, copying only the
--   portion that has changed.
--   
--   <h2>Detailed performance information</h2>
--   
--   An amortized running time is given for each operation, with
--   &lt;math&gt; referring to the length of the sequence and <i>i</i>
--   being the integral index used by some operations. These bounds hold
--   even in a persistent (shared) setting.
--   
--   Despite sequences being structurally strict from a semantic
--   standpoint, they are in fact implemented using laziness internally. As
--   a result, many operations can be performed <i>incrementally</i>,
--   producing their results as they are demanded. This greatly improves
--   performance in some cases. These functions include
--   
--   <ul>
--   <li>The <a>Functor</a> methods <a>fmap</a> and <a>&lt;$</a>, along
--   with <a>mapWithIndex</a></li>
--   <li>The <tt>Applicative</tt> methods <tt>&lt;*&gt;</tt>,
--   <tt>*&gt;</tt>, and <tt>&lt;*</tt></li>
--   <li>The zips: <a>zipWith</a>, <a>zip</a>, etc.</li>
--   <li><a>inits</a>, <a>tails</a></li>
--   <li><a>fromFunction</a>, <a>replicate</a>, <a>intersperse</a>, and
--   <a>cycleTaking</a></li>
--   <li><a>reverse</a></li>
--   <li><a>chunksOf</a></li>
--   </ul>
--   
--   Note that the <a>Monad</a> method, <a>&gt;&gt;=</a>, is not
--   particularly lazy. It will take time proportional to the sum of the
--   logarithms of the individual result sequences to produce anything
--   whatsoever.
--   
--   Several functions take special advantage of sharing to produce results
--   using much less time and memory than one might expect. These are
--   documented individually for functions, but also include certain class
--   methods:
--   
--   <a>&lt;$</a> and <tt>*&gt;</tt> each take time and space proportional
--   to the logarithm of the size of their result.
--   
--   <tt>&lt;*</tt> takes time and space proportional to the product of the
--   length of its first argument and the logarithm of the length of its
--   second argument.
--   
--   <h2>Warning</h2>
--   
--   The size of a <a>Seq</a> must not exceed <tt>maxBound::Int</tt>.
--   Violation of this condition is not detected and if the size limit is
--   exceeded, the behaviour of the sequence is undefined. This is unlikely
--   to occur in most applications, but some care may be required when
--   using <a>&gt;&lt;</a>, <tt>&lt;*&gt;</tt>, <tt>*&gt;</tt>, or
--   <a>&gt;&gt;</a>, particularly repeatedly and particularly in
--   combination with <a>replicate</a> or <a>fromFunction</a>.
--   
--   <h2>Implementation</h2>
--   
--   The implementation uses 2-3 finger trees annotated with sizes, as
--   described in section 4.2 of
--   
--   <ul>
--   <li>Ralf Hinze and Ross Paterson, "<i>Finger trees: a simple
--   general-purpose data structure</i>", Journal of Functional Programming
--   16:2 (2006) pp 197-217.
--   <a>http://staff.city.ac.uk/~ross/papers/FingerTree.html</a>.</li>
--   </ul>
module Data.Sequence

-- | General-purpose finite sequences.
data Seq a

-- | A bidirectional pattern synonym matching an empty sequence.
pattern Empty :: Seq a

-- | A bidirectional pattern synonym viewing the front of a non-empty
--   sequence.
pattern (:<|) :: a -> Seq a -> Seq a

-- | A bidirectional pattern synonym viewing the rear of a non-empty
--   sequence.
pattern (:|>) :: Seq a -> a -> Seq a
infixl 5 :|>
infixr 5 :<|

-- | &lt;math&gt;. The empty sequence.
empty :: Seq a

-- | &lt;math&gt;. A singleton sequence.
singleton :: a -> Seq a

-- | &lt;math&gt;. Add an element to the left end of a sequence. Mnemonic:
--   a triangle with the single element at the pointy end.
(<|) :: a -> Seq a -> Seq a
infixr 5 <|

-- | &lt;math&gt;. Add an element to the right end of a sequence. Mnemonic:
--   a triangle with the single element at the pointy end.
(|>) :: Seq a -> a -> Seq a
infixl 5 |>

-- | &lt;math&gt;. Concatenate two sequences.
(><) :: Seq a -> Seq a -> Seq a
infixr 5 ><

-- | &lt;math&gt;. Create a sequence from a finite list of elements. There
--   is a function <a>toList</a> in the opposite direction for all
--   instances of the <a>Foldable</a> class, including <a>Seq</a>.
fromList :: [a] -> Seq a

-- | &lt;math&gt;. Convert a given sequence length and a function
--   representing that sequence into a sequence.
fromFunction :: Int -> (Int -> a) -> Seq a

-- | &lt;math&gt;. Create a sequence consisting of the elements of an
--   <a>Array</a>. Note that the resulting sequence elements may be
--   evaluated lazily (as on GHC), so you must force the entire structure
--   to be sure that the original array can be garbage-collected.
fromArray :: Ix i => Array i a -> Seq a

-- | &lt;math&gt;. <tt>replicate n x</tt> is a sequence consisting of
--   <tt>n</tt> copies of <tt>x</tt>.
replicate :: Int -> a -> Seq a

-- | <a>replicateA</a> is an <a>Applicative</a> version of
--   <a>replicate</a>, and makes &lt;math&gt; calls to <a>liftA2</a> and
--   <a>pure</a>.
--   
--   <pre>
--   replicateA n x = sequenceA (replicate n x)
--   </pre>
replicateA :: Applicative f => Int -> f a -> f (Seq a)

-- | <a>replicateM</a> is the <tt>Seq</tt> counterpart of
--   <tt>Control.Monad.<a>replicateM</a></tt>.
--   
--   <pre>
--   replicateM n x = sequence (replicate n x)
--   </pre>
--   
--   For <tt>base &gt;= 4.8.0</tt> and <tt>containers &gt;= 0.5.11</tt>,
--   <a>replicateM</a> is a synonym for <a>replicateA</a>.
replicateM :: Applicative m => Int -> m a -> m (Seq a)

-- | &lt;math&gt;. <tt><a>cycleTaking</a> k xs</tt> forms a sequence of
--   length <tt>k</tt> by repeatedly concatenating <tt>xs</tt> with itself.
--   <tt>xs</tt> may only be empty if <tt>k</tt> is 0.
--   
--   <pre>
--   cycleTaking k = fromList . take k . cycle . toList
--   </pre>
cycleTaking :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Constructs a sequence by repeated application of a
--   function to a seed value.
--   
--   <pre>
--   iterateN n f x = fromList (Prelude.take n (Prelude.iterate f x))
--   </pre>
iterateN :: Int -> (a -> a) -> a -> Seq a

-- | Builds a sequence from a seed value. Takes time linear in the number
--   of generated elements. <i>WARNING:</i> If the number of generated
--   elements is infinite, this method will not terminate.
unfoldr :: (b -> Maybe (a, b)) -> b -> Seq a

-- | <tt><a>unfoldl</a> f x</tt> is equivalent to <tt><a>reverse</a>
--   (<a>unfoldr</a> (<a>fmap</a> swap . f) x)</tt>.
unfoldl :: (b -> Maybe (b, a)) -> b -> Seq a

-- | &lt;math&gt;. Is this the empty sequence?
null :: Seq a -> Bool

-- | &lt;math&gt;. The number of elements in the sequence.
length :: Seq a -> Int

-- | View of the left end of a sequence.
data ViewL a

-- | empty sequence
EmptyL :: ViewL a

-- | leftmost element and the rest of the sequence
(:<) :: a -> Seq a -> ViewL a
infixr 5 :<

-- | &lt;math&gt;. Analyse the left end of a sequence.
viewl :: Seq a -> ViewL a

-- | View of the right end of a sequence.
data ViewR a

-- | empty sequence
EmptyR :: ViewR a

-- | the sequence minus the rightmost element, and the rightmost element
(:>) :: Seq a -> a -> ViewR a
infixl 5 :>

-- | &lt;math&gt;. Analyse the right end of a sequence.
viewr :: Seq a -> ViewR a

-- | <a>scanl</a> is similar to <a>foldl</a>, but returns a sequence of
--   reduced values from the left:
--   
--   <pre>
--   scanl f z (fromList [x1, x2, ...]) = fromList [z, z `f` x1, (z `f` x1) `f` x2, ...]
--   </pre>
scanl :: (a -> b -> a) -> a -> Seq b -> Seq a

-- | <a>scanl1</a> is a variant of <a>scanl</a> that has no starting value
--   argument:
--   
--   <pre>
--   scanl1 f (fromList [x1, x2, ...]) = fromList [x1, x1 `f` x2, ...]
--   </pre>
scanl1 :: (a -> a -> a) -> Seq a -> Seq a

-- | <a>scanr</a> is the right-to-left dual of <a>scanl</a>.
scanr :: (a -> b -> b) -> b -> Seq a -> Seq b

-- | <a>scanr1</a> is a variant of <a>scanr</a> that has no starting value
--   argument.
scanr1 :: (a -> a -> a) -> Seq a -> Seq a

-- | &lt;math&gt;. Returns a sequence of all suffixes of this sequence,
--   longest first. For example,
--   
--   <pre>
--   tails (fromList "abc") = fromList [fromList "abc", fromList "bc", fromList "c", fromList ""]
--   </pre>
--   
--   Evaluating the &lt;math&gt;th suffix takes &lt;math&gt;, but
--   evaluating every suffix in the sequence takes &lt;math&gt; due to
--   sharing.
tails :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. Returns a sequence of all prefixes of this sequence,
--   shortest first. For example,
--   
--   <pre>
--   inits (fromList "abc") = fromList [fromList "", fromList "a", fromList "ab", fromList "abc"]
--   </pre>
--   
--   Evaluating the &lt;math&gt;th prefix takes &lt;math&gt;, but
--   evaluating every prefix in the sequence takes &lt;math&gt; due to
--   sharing.
inits :: Seq a -> Seq (Seq a)

-- | &lt;math&gt;. <tt>chunksOf c xs</tt> splits <tt>xs</tt> into chunks of
--   size <tt>c&gt;0</tt>. If <tt>c</tt> does not divide the length of
--   <tt>xs</tt> evenly, then the last element of the result will be short.
--   
--   Side note: the given performance bound is missing some messy terms
--   that only really affect edge cases. Performance degrades smoothly from
--   &lt;math&gt; (for &lt;math&gt;) to &lt;math&gt; (for &lt;math&gt;).
--   The true bound is more like &lt;math&gt;
chunksOf :: Int -> Seq a -> Seq (Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
--   <a>takeWhileL</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns the longest prefix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt>.
takeWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
--   <a>takeWhileR</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns the longest suffix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt>.
--   
--   <tt><a>takeWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
--   (<a>takeWhileL</a> p (<a>reverse</a> xs))</tt>.
takeWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length.
--   <tt><a>dropWhileL</a> p xs</tt> returns the suffix remaining after
--   <tt><a>takeWhileL</a> p xs</tt>.
dropWhileL :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the suffix length.
--   <tt><a>dropWhileR</a> p xs</tt> returns the prefix remaining after
--   <tt><a>takeWhileR</a> p xs</tt>.
--   
--   <tt><a>dropWhileR</a> p xs</tt> is equivalent to <tt><a>reverse</a>
--   (<a>dropWhileL</a> p (<a>reverse</a> xs))</tt>.
dropWhileR :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt; where &lt;math&gt; is the prefix length. <a>spanl</a>,
--   applied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
--   a pair whose first element is the longest prefix (possibly empty) of
--   <tt>xs</tt> of elements that satisfy <tt>p</tt> and the second element
--   is the remainder of the sequence.
spanl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the suffix length. <a>spanr</a>,
--   applied to a predicate <tt>p</tt> and a sequence <tt>xs</tt>, returns
--   a pair whose <i>first</i> element is the longest <i>suffix</i>
--   (possibly empty) of <tt>xs</tt> of elements that satisfy <tt>p</tt>
--   and the second element is the remainder of the sequence.
spanr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt; where &lt;math&gt; is the breakpoint index.
--   <a>breakl</a>, applied to a predicate <tt>p</tt> and a sequence
--   <tt>xs</tt>, returns a pair whose first element is the longest prefix
--   (possibly empty) of <tt>xs</tt> of elements that <i>do not satisfy</i>
--   <tt>p</tt> and the second element is the remainder of the sequence.
--   
--   <tt><a>breakl</a> p</tt> is equivalent to <tt><a>spanl</a> (not .
--   p)</tt>.
breakl :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | <tt><a>breakr</a> p</tt> is equivalent to <tt><a>spanr</a> (not .
--   p)</tt>.
breakr :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>partition</a> function takes a predicate
--   <tt>p</tt> and a sequence <tt>xs</tt> and returns sequences of those
--   elements which do and do not satisfy the predicate.
partition :: (a -> Bool) -> Seq a -> (Seq a, Seq a)

-- | &lt;math&gt;. The <a>filter</a> function takes a predicate <tt>p</tt>
--   and a sequence <tt>xs</tt> and returns a sequence of those elements
--   which satisfy the predicate.
filter :: (a -> Bool) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sort</a> sorts the specified <a>Seq</a> by the
--   natural ordering of its elements. The sort is stable, meaning the
--   order of equal elements is preserved. If stability is not required,
--   <a>unstableSort</a> can be slightly faster.
sort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. <a>sortBy</a> sorts the specified <a>Seq</a> according
--   to the specified comparator. The sort is stable, meaning the order of
--   equal elements is preserved. If stability is not required,
--   <a>unstableSortBy</a> can be slightly faster.
sortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>sortOn</a> sorts the specified <a>Seq</a> by
--   comparing the results of a key function applied to each element. The
--   sort is stable, meaning the order of equal elements is preserved.
--   <tt><a>sortOn</a> f</tt> is equivalent to <tt><a>sortBy</a>
--   (<a>compare</a> <a>`on`</a> f)</tt>, but has the performance advantage
--   of only evaluating <tt>f</tt> once for each element in the input
--   <a>Seq</a>.
--   
--   An example of using <a>sortOn</a> might be to sort a <a>Seq</a> of
--   strings according to their length:
--   
--   <pre>
--   sortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
--   </pre>
--   
--   If, instead, <a>sortBy</a> had been used, <a>length</a> would be
--   evaluated on every comparison, giving &lt;math&gt; evaluations, rather
--   than &lt;math&gt;.
--   
--   If <tt>f</tt> is very cheap (for example a record selector, or
--   <a>fst</a>), <tt><a>sortBy</a> (<a>compare</a> <a>`on`</a> f)</tt>
--   will be faster than <tt><a>sortOn</a> f</tt>.
sortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSort</a> sorts the specified <a>Seq</a> by
--   the natural ordering of its elements, but the sort is not stable. This
--   algorithm is frequently faster and uses less memory than <a>sort</a>.
unstableSort :: Ord a => Seq a -> Seq a

-- | &lt;math&gt;. A generalization of <a>unstableSort</a>,
--   <a>unstableSortBy</a> takes an arbitrary comparator and sorts the
--   specified sequence. The sort is not stable. This algorithm is
--   frequently faster and uses less memory than <a>sortBy</a>.
unstableSortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | &lt;math&gt;. <a>unstableSortOn</a> sorts the specified <a>Seq</a> by
--   comparing the results of a key function applied to each element.
--   <tt><a>unstableSortOn</a> f</tt> is equivalent to
--   <tt><a>unstableSortBy</a> (<a>compare</a> <a>`on`</a> f)</tt>, but has
--   the performance advantage of only evaluating <tt>f</tt> once for each
--   element in the input <a>Seq</a>.
--   
--   An example of using <a>unstableSortOn</a> might be to sort a
--   <a>Seq</a> of strings according to their length:
--   
--   <pre>
--   unstableSortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]
--   </pre>
--   
--   If, instead, <a>unstableSortBy</a> had been used, <a>length</a> would
--   be evaluated on every comparison, giving &lt;math&gt; evaluations,
--   rather than &lt;math&gt;.
--   
--   If <tt>f</tt> is very cheap (for example a record selector, or
--   <a>fst</a>), <tt><a>unstableSortBy</a> (<a>compare</a> <a>`on`</a>
--   f)</tt> will be faster than <tt><a>unstableSortOn</a> f</tt>.
unstableSortOn :: Ord b => (a -> b) -> Seq a -> Seq a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
--   If the specified position is negative or at least the length of the
--   sequence, <a>lookup</a> returns <a>Nothing</a>.
--   
--   <pre>
--   0 &lt;= i &lt; length xs ==&gt; lookup i xs == Just (toList xs !! i)
--   </pre>
--   
--   <pre>
--   i &lt; 0 || i &gt;= length xs ==&gt; lookup i xs = Nothing
--   </pre>
--   
--   Unlike <a>index</a>, this can be used to retrieve an element without
--   forcing it. For example, to insert the fifth element of a sequence
--   <tt>xs</tt> into a <a>Map</a> <tt>m</tt> at key <tt>k</tt>, you could
--   use
--   
--   <pre>
--   case lookup 5 xs of
--     Nothing -&gt; m
--     Just x -&gt; <a>insert</a> k x m
--   </pre>
lookup :: Int -> Seq a -> Maybe a

-- | &lt;math&gt;. A flipped, infix version of <a>lookup</a>.
(!?) :: Seq a -> Int -> Maybe a

-- | &lt;math&gt;. The element at the specified position, counting from 0.
--   The argument should thus be a non-negative integer less than the size
--   of the sequence. If the position is out of range, <a>index</a> fails
--   with an error.
--   
--   <pre>
--   xs `index` i = toList xs !! i
--   </pre>
--   
--   Caution: <a>index</a> necessarily delays retrieving the requested
--   element until the result is forced. It can therefore lead to a space
--   leak if the result is stored, unforced, in another structure. To
--   retrieve an element immediately without forcing it, use <a>lookup</a>
--   or <a>(!?)</a>.
index :: Seq a -> Int -> a

-- | &lt;math&gt;. Update the element at the specified position. If the
--   position is out of range, the original sequence is returned.
--   <a>adjust</a> can lead to poor performance and even memory leaks,
--   because it does not force the new value before installing it in the
--   sequence. <a>adjust'</a> should usually be preferred.
adjust :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Update the element at the specified position. If the
--   position is out of range, the original sequence is returned. The new
--   value is forced before it is installed in the sequence.
--   
--   <pre>
--   adjust' f i xs =
--    case xs !? i of
--      Nothing -&gt; xs
--      Just x -&gt; let !x' = f x
--                in update i x' xs
--   </pre>
adjust' :: (a -> a) -> Int -> Seq a -> Seq a

-- | &lt;math&gt;. Replace the element at the specified position. If the
--   position is out of range, the original sequence is returned.
update :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. The first <tt>i</tt> elements of a sequence. If
--   <tt>i</tt> is negative, <tt><a>take</a> i s</tt> yields the empty
--   sequence. If the sequence contains fewer than <tt>i</tt> elements, the
--   whole sequence is returned.
take :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Elements of a sequence after the first <tt>i</tt>. If
--   <tt>i</tt> is negative, <tt><a>drop</a> i s</tt> yields the whole
--   sequence. If the sequence contains fewer than <tt>i</tt> elements, the
--   empty sequence is returned.
drop :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. <tt><a>insertAt</a> i x xs</tt> inserts <tt>x</tt> into
--   <tt>xs</tt> at the index <tt>i</tt>, shifting the rest of the sequence
--   over.
--   
--   <pre>
--   insertAt 2 x (fromList [a,b,c,d]) = fromList [a,b,x,c,d]
--   insertAt 4 x (fromList [a,b,c,d]) = insertAt 10 x (fromList [a,b,c,d])
--                                     = fromList [a,b,c,d,x]
--   </pre>
--   
--   <pre>
--   insertAt i x xs = take i xs &gt;&lt; singleton x &gt;&lt; drop i xs
--   </pre>
insertAt :: Int -> a -> Seq a -> Seq a

-- | &lt;math&gt;. Delete the element of a sequence at a given index.
--   Return the original sequence if the index is out of range.
--   
--   <pre>
--   deleteAt 2 [a,b,c,d] = [a,b,d]
--   deleteAt 4 [a,b,c,d] = deleteAt (-1) [a,b,c,d] = [a,b,c,d]
--   </pre>
deleteAt :: Int -> Seq a -> Seq a

-- | &lt;math&gt;. Split a sequence at a given position. <tt><a>splitAt</a>
--   i s = (<a>take</a> i s, <a>drop</a> i s)</tt>.
splitAt :: Int -> Seq a -> (Seq a, Seq a)

-- | <a>elemIndexL</a> finds the leftmost index of the specified element,
--   if it is present, and otherwise <a>Nothing</a>.
elemIndexL :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesL</a> finds the indices of the specified element, from
--   left to right (i.e. in ascending order).
elemIndicesL :: Eq a => a -> Seq a -> [Int]

-- | <a>elemIndexR</a> finds the rightmost index of the specified element,
--   if it is present, and otherwise <a>Nothing</a>.
elemIndexR :: Eq a => a -> Seq a -> Maybe Int

-- | <a>elemIndicesR</a> finds the indices of the specified element, from
--   right to left (i.e. in descending order).
elemIndicesR :: Eq a => a -> Seq a -> [Int]

-- | <tt><a>findIndexL</a> p xs</tt> finds the index of the leftmost
--   element that satisfies <tt>p</tt>, if any exist.
findIndexL :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesL</a> p</tt> finds all indices of elements that
--   satisfy <tt>p</tt>, in ascending order.
findIndicesL :: (a -> Bool) -> Seq a -> [Int]

-- | <tt><a>findIndexR</a> p xs</tt> finds the index of the rightmost
--   element that satisfies <tt>p</tt>, if any exist.
findIndexR :: (a -> Bool) -> Seq a -> Maybe Int

-- | <tt><a>findIndicesR</a> p</tt> finds all indices of elements that
--   satisfy <tt>p</tt>, in descending order.
findIndicesR :: (a -> Bool) -> Seq a -> [Int]
foldMapWithIndex :: Monoid m => (Int -> a -> m) -> Seq a -> m

-- | <a>foldlWithIndex</a> is a version of <a>foldl</a> that also provides
--   access to the index of each element.
foldlWithIndex :: (b -> Int -> a -> b) -> b -> Seq a -> b

-- | <a>foldrWithIndex</a> is a version of <a>foldr</a> that also provides
--   access to the index of each element.
foldrWithIndex :: (Int -> a -> b -> b) -> b -> Seq a -> b

-- | A generalization of <a>fmap</a>, <a>mapWithIndex</a> takes a mapping
--   function that also depends on the element's index, and applies it to
--   every element in the sequence.
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b

-- | <a>traverseWithIndex</a> is a version of <a>traverse</a> that also
--   offers access to the index of each element.
traverseWithIndex :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)

-- | &lt;math&gt;. The reverse of a sequence.
reverse :: Seq a -> Seq a

-- | &lt;math&gt;. Intersperse an element between the elements of a
--   sequence.
--   
--   <pre>
--   intersperse a empty = empty
--   intersperse a (singleton x) = singleton x
--   intersperse a (fromList [x,y]) = fromList [x,a,y]
--   intersperse a (fromList [x,y,z]) = fromList [x,a,y,a,z]
--   </pre>
intersperse :: a -> Seq a -> Seq a

-- | &lt;math&gt;. <a>zip</a> takes two sequences and returns a sequence of
--   corresponding pairs. If one input is short, excess elements are
--   discarded from the right end of the longer sequence.
zip :: Seq a -> Seq b -> Seq (a, b)

-- | &lt;math&gt;. <a>zipWith</a> generalizes <a>zip</a> by zipping with
--   the function given as the first argument, instead of a tupling
--   function. For example, <tt>zipWith (+)</tt> is applied to two
--   sequences to take the sequence of corresponding sums.
zipWith :: (a -> b -> c) -> Seq a -> Seq b -> Seq c

-- | &lt;math&gt;. <a>zip3</a> takes three sequences and returns a sequence
--   of triples, analogous to <a>zip</a>.
zip3 :: Seq a -> Seq b -> Seq c -> Seq (a, b, c)

-- | &lt;math&gt;. <a>zipWith3</a> takes a function which combines three
--   elements, as well as three sequences and returns a sequence of their
--   point-wise combinations, analogous to <a>zipWith</a>.
zipWith3 :: (a -> b -> c -> d) -> Seq a -> Seq b -> Seq c -> Seq d

-- | &lt;math&gt;. <a>zip4</a> takes four sequences and returns a sequence
--   of quadruples, analogous to <a>zip</a>.
zip4 :: Seq a -> Seq b -> Seq c -> Seq d -> Seq (a, b, c, d)

-- | &lt;math&gt;. <a>zipWith4</a> takes a function which combines four
--   elements, as well as four sequences and returns a sequence of their
--   point-wise combinations, analogous to <a>zipWith</a>.
zipWith4 :: (a -> b -> c -> d -> e) -> Seq a -> Seq b -> Seq c -> Seq d -> Seq e

-- | Unzip a sequence of pairs.
--   
--   <pre>
--   unzip ps = ps <a>`seq`</a> (<a>fmap</a> <a>fst</a> ps) (<a>fmap</a> <a>snd</a> ps)
--   </pre>
--   
--   Example:
--   
--   <pre>
--   unzip $ fromList [(1,"a"), (2,"b"), (3,"c")] =
--     (fromList [1,2,3], fromList ["a", "b", "c"])
--   </pre>
--   
--   See the note about efficiency at <a>unzipWith</a>.
unzip :: Seq (a, b) -> (Seq a, Seq b)

-- | &lt;math&gt;. Unzip a sequence using a function to divide elements.
--   
--   <pre>
--   unzipWith f xs == <a>unzip</a> (<a>fmap</a> f xs)
--   </pre>
--   
--   Efficiency note:
--   
--   <tt>unzipWith</tt> produces its two results in lockstep. If you
--   calculate <tt> unzipWith f xs </tt> and fully force <i>either</i> of
--   the results, then the entire structure of the <i>other</i> one will be
--   built as well. This behavior allows the garbage collector to collect
--   each calculated pair component as soon as it dies, without having to
--   wait for its mate to die. If you do not need this behavior, you may be
--   better off simply calculating the sequence of pairs and using
--   <a>fmap</a> to extract each component sequence.
unzipWith :: (a -> (b, c)) -> Seq a -> (Seq b, Seq c)


-- | <h1>Multi-way Trees and Forests</h1>
--   
--   The <tt><a>Tree</a> a</tt> type represents a lazy, possibly infinite,
--   multi-way tree (also known as a <i>rose tree</i>).
--   
--   The <tt><a>Forest</a> a</tt> type represents a forest of
--   <tt><a>Tree</a> a</tt>s.
module Data.Tree

-- | Non-empty, possibly infinite, multi-way trees; also known as <i>rose
--   trees</i>.
data Tree a
Node :: a -> [Tree a] -> Tree a

-- | label value
[rootLabel] :: Tree a -> a

-- | zero or more child trees
[subForest] :: Tree a -> [Tree a]

-- | This type synonym exists primarily for historical reasons.
type Forest a = [Tree a]

-- | A newtype over <a>Tree</a> that folds and traverses in post-order.
newtype PostOrder a
PostOrder :: Tree a -> PostOrder a
[unPostOrder] :: PostOrder a -> Tree a

-- | Build a (possibly infinite) tree from a seed value.
--   
--   <tt>unfoldTree f b</tt> constructs a tree by starting with the tree
--   <tt>Node { rootLabel=b, subForest=[] }</tt> and repeatedly applying
--   <tt>f</tt> to each <a>rootLabel</a> value in the tree's leaves to
--   generate its <a>subForest</a>.
--   
--   For a monadic version, see <a>unfoldTreeM</a> (depth-first) and
--   <a>unfoldTreeM_BF</a> (breadth-first).
--   
--   <h4><b>Examples</b></h4>
--   
--   Construct the tree of <tt>Integer</tt>s where each node has two
--   children: <tt>left = 2*x</tt> and <tt>right = 2*x + 1</tt>, where
--   <tt>x</tt> is the <a>rootLabel</a> of the node. Stop when the values
--   exceed 7.
--   
--   <pre>
--   let buildNode x = if 2*x + 1 &gt; 7 then (x, []) else (x, [2*x, 2*x+1])
--   putStr $ drawTree $ fmap show $ unfoldTree buildNode 1
--   </pre>
--   
--   <pre>
--   1
--   |
--   +- 2
--   |  |
--   |  +- 4
--   |  |
--   |  `- 5
--   |
--   `- 3
--      |
--      +- 6
--      |
--      `- 7
--   </pre>
unfoldTree :: (b -> (a, [b])) -> b -> Tree a

-- | Build a (possibly infinite) forest from a list of seed values.
--   
--   <tt>unfoldForest f seeds</tt> invokes <a>unfoldTree</a> on each seed
--   value.
--   
--   For a monadic version, see <a>unfoldForestM</a> (depth-first) and
--   <a>unfoldForestM_BF</a> (breadth-first).
unfoldForest :: (b -> (a, [b])) -> [b] -> [Tree a]

-- | Monadic tree builder, in depth-first order.
unfoldTreeM :: Monad m => (b -> m (a, [b])) -> b -> m (Tree a)

-- | Monadic forest builder, in depth-first order.
unfoldForestM :: Monad m => (b -> m (a, [b])) -> [b] -> m [Tree a]

-- | Monadic tree builder, in breadth-first order.
--   
--   See <a>unfoldTree</a> for more info.
--   
--   Implemented using an algorithm adapted from <i>Breadth-First
--   Numbering: Lessons from a Small Exercise in Algorithm Design</i>, by
--   Chris Okasaki, <i>ICFP'00</i>.
unfoldTreeM_BF :: Monad m => (b -> m (a, [b])) -> b -> m (Tree a)

-- | Monadic forest builder, in breadth-first order.
--   
--   See <a>unfoldForest</a> for more info.
--   
--   Implemented using an algorithm adapted from <i>Breadth-First
--   Numbering: Lessons from a Small Exercise in Algorithm Design</i>, by
--   Chris Okasaki, <i>ICFP'00</i>.
unfoldForestM_BF :: Monad m => (b -> m (a, [b])) -> [b] -> m [Tree a]

-- | Fold a tree into a "summary" value.
--   
--   For each node in the tree, apply <tt>f</tt> to the <tt>rootLabel</tt>
--   and the result of applying <tt>f</tt> to each <tt>subForest</tt>.
--   
--   This is also known as the catamorphism on trees.
--   
--   <h4><b>Examples</b></h4>
--   
--   Sum the values in a tree:
--   
--   <pre>
--   foldTree (\x xs -&gt; sum (x:xs)) (Node 1 [Node 2 [], Node 3 []]) == 6
--   </pre>
--   
--   Find the maximum value in the tree:
--   
--   <pre>
--   foldTree (\x xs -&gt; maximum (x:xs)) (Node 1 [Node 2 [], Node 3 []]) == 3
--   </pre>
--   
--   Count the number of leaves in the tree:
--   
--   <pre>
--   foldTree (\_ xs -&gt; if null xs then 1 else sum xs) (Node 1 [Node 2 [], Node 3 []]) == 2
--   </pre>
--   
--   Find depth of the tree; i.e. the number of branches from the root of
--   the tree to the furthest leaf:
--   
--   <pre>
--   foldTree (\_ xs -&gt; if null xs then 0 else 1 + maximum xs) (Node 1 [Node 2 [], Node 3 []]) == 1
--   </pre>
--   
--   You can even implement traverse using foldTree:
--   
--   <pre>
--   traverse' f = foldTree (\x xs -&gt; liftA2 Node (f x) (sequenceA xs))
--   </pre>
foldTree :: (a -> [b] -> b) -> Tree a -> b

-- | Returns the elements of a tree in pre-order.
--   
--   <pre>
--   flatten == Data.Foldable.<a>toList</a>
--   </pre>
--   
--   <pre>
--     a
--    / \    =&gt; [a,b,c]
--   b   c
--   </pre>
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   flatten (Node 1 [Node 2 [], Node 3 []]) == [1,2,3]
--   </pre>
flatten :: Tree a -> [a]

-- | Returns the list of nodes at each level of the tree.
--   
--   <pre>
--     a
--    / \    =&gt; [[a], [b,c]]
--   b   c
--   </pre>
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   levels (Node 1 [Node 2 [], Node 3 []]) == [[1],[2,3]]
--   </pre>
levels :: Tree a -> [[a]]

-- | &lt;math&gt;. The leaves of the tree in left-to-right order.
--   
--   A leaf is a node with no children.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   leaves $
--     Node 1
--       [ Node 2
--           [ Node 4 []
--           , Node 5 []
--           ]
--       , Node 3
--           [ Node 6 []
--           ]
--       ]
--   :}
--   [4,5,6]
--   
--   &gt;&gt;&gt; leaves (Node "root" [])
--   ["root"]
--   </pre>
leaves :: Tree a -> [a]

-- | &lt;math&gt;. The edges of the tree as parent-child pairs in
--   pre-order.
--   
--   A tree with &lt;math&gt; nodes has &lt;math&gt; edges.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   edges $
--     Node 1
--       [ Node 2
--           [ Node 4 []
--           , Node 5 []
--           ]
--       , Node 3
--           [ Node 6 []
--           ]
--       ]
--   :}
--   [(1,2),(2,4),(2,5),(1,3),(3,6)]
--   
--   &gt;&gt;&gt; edges (Node "root" [])
--   []
--   </pre>
edges :: Tree a -> [(a, a)]

-- | &lt;math&gt;. Labels on the paths from each node to the root.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   pathsToRoot $
--     Node 1
--       [ Node 2 []
--       , Node 3 []
--       ]
--   :}
--   Node {rootLabel = 1 :| [], subForest = [Node {rootLabel = 2 :| [1], subForest = []},Node {rootLabel = 3 :| [1], subForest = []}]}
--   
--   &gt;&gt;&gt; pathsToRoot (Node "root" [])
--   Node {rootLabel = "root" :| [], subForest = []}
--   </pre>
pathsToRoot :: Tree a -> Tree (NonEmpty a)

-- | Labels on the paths from the root to each node.
--   
--   If the path orientation is not important, consider using
--   <a>pathsToRoot</a> instead because it is more efficient.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   pathsFromRoot $
--     Node 1
--       [ Node 2 []
--       , Node 3 []
--       ]
--   :}
--   Node {rootLabel = 1 :| [], subForest = [Node {rootLabel = 1 :| [2], subForest = []},Node {rootLabel = 1 :| [3], subForest = []}]}
--   
--   &gt;&gt;&gt; pathsFromRoot (Node "root" [])
--   Node {rootLabel = "root" :| [], subForest = []}
--   </pre>
pathsFromRoot :: Tree a -> Tree (NonEmpty a)

-- | 2-dimensional ASCII drawing of a tree.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   putStr $ drawTree $ fmap show (Node 1 [Node 2 [], Node 3 []])
--   </pre>
--   
--   <pre>
--   1
--   |
--   +- 2
--   |
--   `- 3
--   </pre>
drawTree :: Tree String -> String

-- | 2-dimensional ASCII drawing of a forest.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   putStr $ drawForest $ map (fmap show) [(Node 1 [Node 2 [], Node 3 []]), (Node 10 [Node 20 []])]
--   </pre>
--   
--   <pre>
--   1
--   |
--   +- 2
--   |
--   `- 3
--   
--   10
--   |
--   `- 20
--   </pre>
drawForest :: [Tree String] -> String
instance GHC.Internal.Base.Applicative Data.Tree.Tree
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Tree.PostOrder a)
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.Tree.Tree a)
instance Data.Functor.Classes.Eq1 Data.Tree.Tree
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Tree.PostOrder a)
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.Tree.Tree a)
instance Data.Foldable1.Foldable1 Data.Tree.PostOrder
instance Data.Foldable1.Foldable1 Data.Tree.Tree
instance GHC.Internal.Data.Foldable.Foldable Data.Tree.PostOrder
instance GHC.Internal.Data.Foldable.Foldable Data.Tree.Tree
instance GHC.Internal.Base.Functor Data.Tree.PostOrder
instance GHC.Internal.Base.Functor Data.Tree.Tree
instance GHC.Internal.Generics.Generic1 Data.Tree.PostOrder
instance GHC.Internal.Generics.Generic1 Data.Tree.Tree
instance GHC.Internal.Generics.Generic (Data.Tree.PostOrder a)
instance GHC.Internal.Generics.Generic (Data.Tree.Tree a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Tree.PostOrder a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.Tree.Tree a)
instance GHC.Internal.Control.Monad.Fix.MonadFix Data.Tree.Tree
instance GHC.Internal.Base.Monad Data.Tree.Tree
instance GHC.Internal.Control.Monad.Zip.MonadZip Data.Tree.Tree
instance Control.DeepSeq.NFData1 Data.Tree.Tree
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Tree.Tree a)
instance Data.Functor.Classes.Ord1 Data.Tree.Tree
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Tree.PostOrder a)
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.Tree.Tree a)
instance Data.Functor.Classes.Read1 Data.Tree.Tree
instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Tree.PostOrder a)
instance GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Tree.Tree a)
instance Data.Functor.Classes.Show1 Data.Tree.Tree
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Tree.PostOrder a)
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.Tree.Tree a)
instance GHC.Internal.Data.Traversable.Traversable Data.Tree.PostOrder
instance GHC.Internal.Data.Traversable.Traversable Data.Tree.Tree


-- | <h1>Finite Graphs</h1>
--   
--   The <tt><a>Graph</a></tt> type is an adjacency list representation of
--   a finite, directed graph with vertices of type <tt>Int</tt>.
--   
--   The <tt><a>SCC</a></tt> type represents a <a>strongly-connected
--   component</a> of a graph.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on
--   
--   <ul>
--   <li>David King and John Launchbury, "<i>Structuring Depth-First Search
--   Algorithms in Haskell</i>", Proceedings of the 22nd ACM SIGPLAN-SIGACT
--   Symposium on Principles of Programming Languages, 344-354, 1995,
--   <a>https://doi.org/10.1145/199448.199530</a>.</li>
--   </ul>
module Data.Graph

-- | Adjacency list representation of a graph, mapping each vertex to its
--   list of successors.
type Graph = Array Vertex [Vertex]

-- | The bounds of an <tt>Array</tt>.
type Bounds = (Vertex, Vertex)

-- | An edge from the first vertex to the second.
type Edge = (Vertex, Vertex)

-- | Abstract representation of vertices.
type Vertex = Int

-- | Table indexed by a contiguous set of vertices.
--   
--   <i>Note: This is included for backwards compatibility.</i>
type Table a = Array Vertex a

-- | &lt;math&gt;. Build a graph from a list of nodes uniquely identified
--   by keys, with a list of keys of nodes this node should have edges to.
--   
--   This function takes an adjacency list representing a graph with
--   vertices of type <tt>key</tt> labeled by values of type <tt>node</tt>
--   and produces a <tt>Graph</tt>-based representation of that list. The
--   <tt>Graph</tt> result represents the <i>shape</i> of the graph, and
--   the functions describe a) how to retrieve the label and adjacent
--   vertices of a given vertex, and b) how to retrieve a vertex given a
--   key.
--   
--   <pre>
--   (graph, nodeFromVertex, vertexFromKey) = graphFromEdges edgeList
--   </pre>
--   
--   <ul>
--   <li><tt>graph :: Graph</tt> is the raw, array based adjacency list for
--   the graph.</li>
--   <li><tt>nodeFromVertex :: Vertex -&gt; (node, key, [key])</tt> returns
--   the node associated with the given 0-based <tt>Int</tt> vertex; see
--   <i>warning</i> below. This runs in &lt;math&gt; time.</li>
--   <li><tt>vertexFromKey :: key -&gt; Maybe Vertex</tt> returns the
--   <tt>Int</tt> vertex for the key if it exists in the graph,
--   <tt>Nothing</tt> otherwise. This runs in &lt;math&gt; time.</li>
--   </ul>
--   
--   To safely use this API you must either extract the list of vertices
--   directly from the graph or first call <tt>vertexFromKey k</tt> to
--   check if a vertex corresponds to the key <tt>k</tt>. Once it is known
--   that a vertex exists you can use <tt>nodeFromVertex</tt> to access the
--   labelled node and adjacent vertices. See below for examples.
--   
--   Note: The out-list may contain keys that don't correspond to nodes of
--   the graph; they are ignored.
--   
--   Warning: The <tt>nodeFromVertex</tt> function will cause a runtime
--   exception if the given <tt>Vertex</tt> does not exist.
--   
--   <h4><b>Examples</b></h4>
--   
--   An empty graph.
--   
--   <pre>
--   (graph, nodeFromVertex, vertexFromKey) = graphFromEdges []
--   graph = array (0,-1) []
--   </pre>
--   
--   A graph where the out-list references unspecified nodes
--   (<tt>'c'</tt>), these are ignored.
--   
--   <pre>
--   (graph, _, _) = graphFromEdges [("a", 'a', ['b']), ("b", 'b', ['c'])]
--   array (0,1) [(0,[1]),(1,[])]
--   </pre>
--   
--   A graph with 3 vertices: ("a") -&gt; ("b") -&gt; ("c")
--   
--   <pre>
--   (graph, nodeFromVertex, vertexFromKey) = graphFromEdges [("a", 'a', ['b']), ("b", 'b', ['c']), ("c", 'c', [])]
--   graph == array (0,2) [(0,[1]),(1,[2]),(2,[])]
--   nodeFromVertex 0 == ("a",'a',"b")
--   vertexFromKey 'a' == Just 0
--   </pre>
--   
--   Get the label for a given key.
--   
--   <pre>
--   let getNodePart (n, _, _) = n
--   (graph, nodeFromVertex, vertexFromKey) = graphFromEdges [("a", 'a', ['b']), ("b", 'b', ['c']), ("c", 'c', [])]
--   getNodePart . nodeFromVertex &lt;$&gt; vertexFromKey 'a' == Just "A"
--   </pre>
graphFromEdges :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)

-- | &lt;math&gt;. Identical to <a>graphFromEdges</a>, except that the
--   return value does not include the function which maps keys to
--   vertices. This version of <a>graphFromEdges</a> is for backwards
--   compatibility.
graphFromEdges' :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]))

-- | &lt;math&gt;. Build a graph from a list of edges.
--   
--   Warning: This function will cause a runtime exception if a vertex in
--   the edge list is not within the given <tt>Bounds</tt>.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   buildG (0,-1) [] == array (0,-1) []
--   buildG (0,2) [(0,1), (1,2)] == array (0,1) [(0,[1]),(1,[2])]
--   buildG (0,2) [(0,1), (0,2), (1,2)] == array (0,2) [(0,[2,1]),(1,[2]),(2,[])]
--   </pre>
buildG :: Bounds -> [Edge] -> Graph

-- | &lt;math&gt;. Returns the list of vertices in the graph.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   vertices (buildG (0,-1) []) == []
--   </pre>
--   
--   <pre>
--   vertices (buildG (0,2) [(0,1),(1,2)]) == [0,1,2]
--   </pre>
vertices :: Graph -> [Vertex]

-- | &lt;math&gt;. Returns the list of edges in the graph.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   edges (buildG (0,-1) []) == []
--   </pre>
--   
--   <pre>
--   edges (buildG (0,2) [(0,1),(1,2)]) == [(0,1),(1,2)]
--   </pre>
edges :: Graph -> [Edge]

-- | &lt;math&gt;. A table of the count of edges from each node.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   outdegree (buildG (0,-1) []) == array (0,-1) []
--   </pre>
--   
--   <pre>
--   outdegree (buildG (0,2) [(0,1), (1,2)]) == array (0,2) [(0,1),(1,1),(2,0)]
--   </pre>
outdegree :: Graph -> Array Vertex Int

-- | &lt;math&gt;. A table of the count of edges into each node.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   indegree (buildG (0,-1) []) == array (0,-1) []
--   </pre>
--   
--   <pre>
--   indegree (buildG (0,2) [(0,1), (1,2)]) == array (0,2) [(0,0),(1,1),(2,1)]
--   </pre>
indegree :: Graph -> Array Vertex Int

-- | &lt;math&gt;. The graph obtained by reversing all edges.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   transposeG (buildG (0,2) [(0,1), (1,2)]) == array (0,2) [(0,[]),(1,[0]),(2,[1])]
--   </pre>
transposeG :: Graph -> Graph

-- | &lt;math&gt;. A spanning forest of the part of the graph reachable
--   from the listed vertices, obtained from a depth-first search of the
--   graph starting at each of the listed vertices in order.
dfs :: Graph -> [Vertex] -> [Tree Vertex]

-- | &lt;math&gt;. A spanning forest of the graph, obtained from a
--   depth-first search of the graph starting from each vertex in an
--   unspecified order.
dff :: Graph -> [Tree Vertex]

-- | &lt;math&gt;. A topological sort of the graph. The order is partially
--   specified by the condition that a vertex <i>i</i> precedes <i>j</i>
--   whenever <i>j</i> is reachable from <i>i</i> but not vice versa.
--   
--   Note: A topological sort exists only when there are no cycles in the
--   graph. If the graph has cycles, the output of this function will not
--   be a topological sort. In such a case consider using <a>scc</a>.
topSort :: Graph -> [Vertex]

-- | &lt;math&gt;. Reverse ordering of <a>topSort</a>.
--   
--   See note in <a>topSort</a>.
reverseTopSort :: Graph -> [Vertex]

-- | &lt;math&gt;. The connected components of a graph. Two vertices are
--   connected if there is a path between them, traversing edges in either
--   direction.
components :: Graph -> [Tree Vertex]

-- | &lt;math&gt;. The strongly connected components of a graph, in reverse
--   topological order.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   scc (buildG (0,3) [(3,1),(1,2),(2,0),(0,1)])
--     == [Node {rootLabel = 0, subForest = [Node {rootLabel = 1, subForest = [Node {rootLabel = 2, subForest = []}]}]}
--        ,Node {rootLabel = 3, subForest = []}]
--   </pre>
scc :: Graph -> [Tree Vertex]

-- | &lt;math&gt;. The biconnected components of a graph. An undirected
--   graph is biconnected if the deletion of any vertex leaves it
--   connected.
--   
--   The input graph is expected to be undirected, i.e. for every edge in
--   the graph the reverse edge is also in the graph. If the graph is not
--   undirected the output is arbitrary.
bcc :: Graph -> [Tree [Vertex]]

-- | &lt;math&gt;. Returns the list of vertices reachable from a given
--   vertex.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   reachable (buildG (0,0) []) 0 == [0]
--   </pre>
--   
--   <pre>
--   reachable (buildG (0,2) [(0,1), (1,2)]) 0 == [0,1,2]
--   </pre>
reachable :: Graph -> Vertex -> [Vertex]

-- | &lt;math&gt;. Returns <tt>True</tt> if the second vertex reachable
--   from the first.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   path (buildG (0,0) []) 0 0 == True
--   </pre>
--   
--   <pre>
--   path (buildG (0,2) [(0,1), (1,2)]) 0 2 == True
--   </pre>
--   
--   <pre>
--   path (buildG (0,2) [(0,1), (1,2)]) 2 0 == False
--   </pre>
path :: Graph -> Vertex -> Vertex -> Bool

-- | Strongly connected component.
data SCC vertex

-- | A single vertex that is not in any cycle.
AcyclicSCC :: vertex -> SCC vertex

-- | A maximal set of mutually reachable vertices.
NECyclicSCC :: NonEmpty vertex -> SCC vertex

-- | Partial pattern synonym for backward compatibility with <tt>containers
--   &lt; 0.7</tt>.
pattern CyclicSCC :: [vertex] -> SCC vertex

-- | &lt;math&gt;. The strongly connected components of a directed graph,
--   reverse topologically sorted.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   stronglyConnComp [("a",0,[1]),("b",1,[2,3]),("c",2,[1]),("d",3,[3])]
--     == [CyclicSCC ["d"],CyclicSCC ["b","c"],AcyclicSCC "a"]
--   </pre>
stronglyConnComp :: Ord key => [(node, key, [key])] -> [SCC node]

-- | &lt;math&gt;. The strongly connected components of a directed graph,
--   reverse topologically sorted. The function is the same as
--   <a>stronglyConnComp</a>, except that all the information about each
--   node retained. This interface is used when you expect to apply
--   <a>SCC</a> to (some of) the result of <a>SCC</a>, so you don't want to
--   lose the dependency information.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   stronglyConnCompR [("a",0,[1]),("b",1,[2,3]),("c",2,[1]),("d",3,[3])]
--    == [CyclicSCC [("d",3,[3])],CyclicSCC [("b",1,[2,3]),("c",2,[1])],AcyclicSCC ("a",0,[1])]
--   </pre>
stronglyConnCompR :: Ord key => [(node, key, [key])] -> [SCC (node, key, [key])]

-- | The vertices of a strongly connected component.
--   
--   <tt>flattenSCC = <a>toList</a> . <a>flattenSCC1</a></tt>.
--   
--   This function is retained for backward compatibility,
--   <a>flattenSCC1</a> has the more precise type.
flattenSCC :: SCC vertex -> [vertex]

-- | The vertices of a strongly connected component.
flattenSCC1 :: SCC vertex -> NonEmpty vertex

-- | The vertices of a list of strongly connected components.
flattenSCCs :: [SCC a] -> [a]

-- | This type synonym exists primarily for historical reasons.
type Forest a = [Tree a]

-- | Non-empty, possibly infinite, multi-way trees; also known as <i>rose
--   trees</i>.
data Tree a
Node :: a -> [Tree a] -> Tree a
instance GHC.Internal.Data.Data.Data vertex => GHC.Internal.Data.Data.Data (Data.Graph.SCC vertex)
instance Data.Functor.Classes.Eq1 Data.Graph.SCC
instance GHC.Internal.Classes.Eq vertex => GHC.Internal.Classes.Eq (Data.Graph.SCC vertex)
instance Data.Foldable1.Foldable1 Data.Graph.SCC
instance GHC.Internal.Data.Foldable.Foldable Data.Graph.SCC
instance GHC.Internal.Base.Functor Data.Graph.SCC
instance GHC.Internal.Generics.Generic1 Data.Graph.SCC
instance GHC.Internal.Generics.Generic (Data.Graph.SCC vertex)
instance GHC.Internal.TH.Lift.Lift vertex => GHC.Internal.TH.Lift.Lift (Data.Graph.SCC vertex)
instance Control.DeepSeq.NFData1 Data.Graph.SCC
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Graph.SCC a)
instance Data.Functor.Classes.Read1 Data.Graph.SCC
instance GHC.Internal.Read.Read vertex => GHC.Internal.Read.Read (Data.Graph.SCC vertex)
instance Data.Functor.Classes.Show1 Data.Graph.SCC
instance GHC.Internal.Show.Show vertex => GHC.Internal.Show.Show (Data.Graph.SCC vertex)
instance GHC.Internal.Data.Traversable.Traversable Data.Graph.SCC


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Maps (lazy interface internals)</h1>
--   
--   The <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>k</tt> to values of type
--   <tt>v</tt>. A <a>Map</a> is strict in its keys but lazy in its values.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Map</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
module Data.Map.Internal

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a
Bin :: Size -> k -> a -> Map k a -> Map k a -> Map k a
Tip :: Map k a
type Size = Int

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
--   </pre>
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | &lt;math&gt;. The number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: Map k a -> Int

-- | &lt;math&gt;. Is the key a member of the map? See also
--   <a>notMember</a>.
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map? See also
--   <a>member</a>.
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Look up the value at a key in the map.
--   
--   The function will return the corresponding value as <tt>(<a>Just</a>
--   value)</tt>, or <a>Nothing</a> if the key isn't in the map.
--   
--   An example of using <tt>lookup</tt>:
--   
--   <pre>
--   import Prelude hiding (lookup)
--   import Data.Map
--   
--   employeeDept = fromList([("John","Sales"), ("Bob","IT")])
--   deptCountry = fromList([("IT","USA"), ("Sales","France")])
--   countryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
--   
--   employeeCurrency :: String -&gt; Maybe String
--   employeeCurrency name = do
--       dept &lt;- lookup name employeeDept
--       country &lt;- lookup dept deptCountry
--       lookup country countryCurrency
--   
--   main = do
--       putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
--       putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
--   </pre>
--   
--   The output of this program:
--   
--   <pre>
--   John's currency: Just "Euro"
--   Pete's currency: Nothing
--   </pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns default value
--   <tt>def</tt> when the key is not in the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | &lt;math&gt;. A map with a single element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: k -> a -> Map k a

-- | &lt;math&gt;. Insert a new key and value in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
--   <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining new value and old
--   value. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert the pair <tt>(key, f
--   new_value old_value)</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining key, new value and old
--   value. <tt><a>insertWithKey</a> f key value mp</tt> will insert the
--   pair (key, value) into <tt>mp</tt> if key does not exist in the map.
--   If the key does exist, the function will insert the pair <tt>(key,f
--   key new_value old_value)</tt>. Note that the key passed to f is the
--   same key passed to <a>insertWithKey</a>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Combines insert operation with old value retrieval. The
--   expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a pair
--   where the first element is equal to (<tt><a>lookup</a> k map</tt>) and
--   the second element equal to (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | &lt;math&gt;. Update a value at a specific key with the result of the
--   provided function. When the key is not a member of the map, the
--   original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>updateWithKey</a> f k map</tt>)
--   updates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
--   (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Look up and update. See also <a>updateWithKey</a>. This
--   function returns the changed value, if it is updated. Returns the
--   original key value if the map entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in a <a>Map</a>. In
--   short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
--   m)</tt>.
--   
--   <pre>
--   let f _ = Nothing
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   
--   let f _ = Just "c"
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
--   </pre>
--   
--   Note that <tt><a>adjust</a> = alter . fmap</tt>.
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in a
--   <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a> f k
--   m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map. When used with
--   trivial functors like <a>Identity</a> and <a>Const</a>, it is often
--   slightly slower than more specialized combinators like <a>lookup</a>
--   and <a>insert</a>. However, when the functor is non-trivial and key
--   comparison is not particularly cheap, it is the fastest way.
--   
--   Note on rewrite rules:
--   
--   This module includes GHC rewrite rules to optimize <a>alterF</a> for
--   the <a>Const</a> and <a>Identity</a> functors. In general, these rules
--   improve performance. The sole exception is that when using
--   <a>Identity</a>, deleting a key that is already absent takes longer
--   than it would without the rules. If you expect this to occur a very
--   large fraction of the time, you might consider using a private copy of
--   the <a>Identity</a> type.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | &lt;math&gt;. The expression (<tt><a>union</a> t1 t2</tt>) takes the
--   left-biased union of <tt>t1</tt> and <tt>t2</tt>. It prefers
--   <tt>t1</tt> when duplicate keys are encountered, i.e.
--   (<tt><a>union</a> == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
--   <a>union</a> <a>empty</a></tt>).
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: (Foldable f, Ord k) => f (Map k a) -> Map k a

-- | The union of a list of maps, with a combining operation:
--   (<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
--   <a>empty</a></tt>).
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: (Foldable f, Ord k) => (a -> a -> a) -> f (Map k a) -> Map k a

-- | &lt;math&gt;. Difference of two maps. Return elements of the first map
--   not existing in the second map.
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Difference with a combining function. When two equal
--   keys are encountered, the combining function is applied to the values
--   of these keys. If it returns <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection of two maps. Return data in the first map
--   for the keys existing in both maps. (<tt><a>intersection</a> m1 m2 ==
--   <a>intersectionWith</a> <a>const</a> m1 m2</tt>).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e., their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord k => Map k a -> Map k b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.Map.Strict</a> exposed a version
--   of <a>compose</a> that forced the values of the output <a>Map</a>.
--   This version does not force these values.
--   
--   <h4><b>Note on complexity</b></h4>
--   
--   This function is asymptotically optimal. Given <tt>n :: Map a b, m ::
--   Map b c</tt>, the composition essentially maps each <tt>a</tt> in
--   <tt>n</tt> to <tt>Maybe c</tt>, since the composed lookup yields
--   either one of the <tt>c</tt> in <tt>m</tt> or <tt>Nothing</tt>. The
--   number of possible such mappings is &lt;math&gt;. We now follow a
--   similar reasoning to the one for <a>sorting</a>. To distinguish
--   between &lt;math&gt; possible values, we need &lt;math&gt; bits. Thus,
--   we have a lower bound of &lt;math&gt; bits. <tt>Map</tt> lookups are
--   comparison-based, and each comparison gives us at most one bit of
--   information: in the worst case we'll always be left with at least half
--   of the remaining possible values, meaning we need at least as many
--   comparisons as we need bits.
compose :: Ord b => Map b c -> Map a b -> Map a c

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; Maybe z
--   </tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt;
--   Maybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge preserveMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge preserveMissing preserveMissing (zipWithMaybeMatched $ \ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (mapMissing f) (mapMissing g) (zipWithMatched h)
--   </pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
--                       -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
--                  -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) k x y. Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Force the entries whose keys are missing from the other map and
--   otherwise preserve them unchanged.
--   
--   <pre>
--   preserveMissing' :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing' = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just $! x)
--   </pre>
--   
--   but <tt>preserveMissing'</tt> is quite a bit faster.
preserveMissing' :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) k x. Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMissing f k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
--   </tt>.
data WhenMissing (f :: Type -> Type) k x y
WhenMissing :: (Map k x -> f (Map k y)) -> (k -> x -> f (Maybe y)) -> WhenMissing (f :: Type -> Type) k x y
[missingSubtree] :: WhenMissing (f :: Type -> Type) k x y -> Map k x -> f (Map k y)
[missingKey] :: WhenMissing (f :: Type -> Type) k x y -> k -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
--   (Maybe z) </tt>.
newtype WhenMatched (f :: Type -> Type) k x y z
WhenMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched (f :: Type -> Type) k x y z
[matchedKey] :: WhenMatched (f :: Type -> Type) k x y z -> k -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <tt>mergeA</tt> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | &lt;math&gt;. An unsafe general combining function.
--   
--   <b>Warning</b>: This function can produce corrupt maps and its results
--   may depend on the internal structures of its inputs. Users should
--   prefer <a>merge</a> or <a>mergeA</a>.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>Map</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt>,
--   <tt><a>filterWithKey</a> f</tt>, or <tt><a>mapMaybeWithKey</a> f</tt>
--   could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
--   &lt;$&gt; <a>traverse</a> (\(k, v) -&gt; (,) k &lt;$&gt; f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | &lt;math&gt;. The function <a>mapAccum</a> threads an accumulating
--   argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumWithKey</a> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumRWithKey</a> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>. The value at the greater of the two
--   original keys is used as the first argument to <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   valid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
--   valid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
--   </pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: Map k a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: Map k a -> [k]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Return all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: Map k a -> [(k, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
--   keysSet empty == Data.Set.empty
--   </pre>
keysSet :: Map k a -> Set k

-- | &lt;math&gt;. The set of all elements of the map contained in
--   <a>Arg</a>s.
--   
--   <pre>
--   argSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [Arg 3 "b",Arg 5 "a"]
--   argSet empty == Data.Set.empty
--   </pre>
argSet :: Map k a -> Set (Arg k a)

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.Set.empty == empty
--   </pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | &lt;math&gt;. Build a map from a set of elements contained inside
--   <a>Arg</a>s.
--   
--   <pre>
--   fromArgSet (Data.Set.fromList [Arg 3 "aaa", Arg 5 "aaaaa"]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromArgSet Data.Set.empty == empty
--   </pre>
fromArgSet :: Set (Arg k a) -> Map k a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Build a map from a list of key/value pairs. See also
--   <a>fromAscList</a>. If the list contains more than one value for the
--   same key, the last value for the key is retained.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Build a map from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
--   valid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
--   valid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
--   </pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
--   fromDescList [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
--   valid (fromDistinctDescList [(5,"a"), (5,"b"), (3,"b")]) == False
--   </pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Filter all values that satisfy the predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys that satisfy the predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys/values that satisfy the predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all keys
--   <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j &gt;= p
--   k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partitionWithKey (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first key and to fail after
--   the last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Restrict a <a>Map</a> to only those keys found in a
--   <a>Set</a>.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   m `restrictKeys` s = m <a>`intersection`</a> <a>fromSet</a> (const ()) s
--   </pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Remove all keys in a <a>Set</a> from a <a>Map</a>.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   m `withoutKeys` s = m <a>`difference`</a> <a>fromSet</a> (const ()) s
--   </pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller than
--   <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>splitLookup</a> k map</tt>)
--   splits a map just like <a>split</a> but also returns <tt><a>lookup</a>
--   k map</tt>.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | &lt;math&gt;. This function is defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f t1 t2</tt>)
--   returns <a>True</a> if all keys in <tt>t1</tt> are in tree
--   <tt>t2</tt>, and when <tt>f</tt> returns <a>True</a> when applied to
--   their respective values. For example, the following expressions are
--   all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
--   </pre>
--   
--   Note that <tt>isSubmapOfBy (_ _ -&gt; True) m1 m2</tt> tests whether
--   all the keys in <tt>m1</tt> are also keys in <tt>m2</tt>.
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Look up the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   
--   <pre>
--   isJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
--   fromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
--   fromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
--   isJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
--   </pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   Calls <a>error</a> when the key is not a <a>member</a> of the map.
--   
--   <pre>
--   findIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   findIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
--   findIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
--   findIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   </pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
--   elemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
elemAt :: Int -> Map k a -> (k, a)

-- | &lt;math&gt;. Update the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   updateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
--   updateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
--   updateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   updateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   updateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   deleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   deleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
--   deleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
--   </pre>
deleteAt :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Take a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Drop a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Split a map at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
--   lookupMin empty = Nothing
--   </pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
--   lookupMax empty = Nothing
--   </pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   findMin empty                            Error: empty map has no minimal element
--   </pre>
findMin :: Map k a -> (k, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMax (fromList [(5,"a"), (3,"b")]) == (5,"a")
--   findMax empty                            Error: empty map has no maximal element
--   </pre>
findMax :: Map k a -> (k, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
--   deleteMin empty == empty
--   </pre>
deleteMin :: Map k a -> Map k a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
--   deleteMax empty == empty
--   </pre>
deleteMax :: Map k a -> Map k a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
--   deleteFindMin empty                                      Error: can not return the minimal element of an empty map
--   </pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
--   deleteFindMax empty                                      Error: can not return the maximal element of an empty map
--   </pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Retrieves the value associated with minimal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   minView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
--   minView empty == Nothing
--   </pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the value associated with maximal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   maxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
--   maxView empty == Nothing
--   </pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)
data AreWeStrict
Strict :: AreWeStrict
Lazy :: AreWeStrict
atKeyImpl :: (Functor f, Ord k) => AreWeStrict -> k -> (Maybe a -> f (Maybe a)) -> Map k a -> f (Map k a)
atKeyPlain :: Ord k => AreWeStrict -> k -> (Maybe a -> Maybe a) -> Map k a -> Map k a
bin :: k -> a -> Map k a -> Map k a -> Map k a
balance :: k -> a -> Map k a -> Map k a -> Map k a
balanceL :: k -> a -> Map k a -> Map k a -> Map k a
balanceR :: k -> a -> Map k a -> Map k a -> Map k a
delta :: Int
insertMax :: k -> a -> Map k a -> Map k a
link :: k -> a -> Map k a -> Map k a -> Map k a
link2 :: Map k a -> Map k a -> Map k a
glue :: Map k a -> Map k a -> Map k a
ascLinkTop :: Stack k a -> Int -> Map k a -> k -> a -> Stack k a
ascLinkAll :: Stack k a -> Map k a
descLinkTop :: k -> a -> Int -> Map k a -> Stack k a -> Stack k a
descLinkAll :: Stack k a -> Map k a
data MaybeS a
NothingS :: MaybeS a
JustS :: a -> MaybeS a
newtype Identity a
Identity :: a -> Identity a
[runIdentity] :: Identity a -> a
data Stack k a
Push :: k -> a -> Map k a -> Stack k a -> Stack k a
Nada :: Stack k a
foldl'Stack :: (b -> k -> a -> Map k a -> b) -> b -> Stack k a -> b
data MapBuilder k a
BAsc :: Stack k a -> MapBuilder k a
BMap :: Map k a -> MapBuilder k a
emptyB :: MapBuilder k a
insertB :: Ord k => k -> a -> MapBuilder k a -> MapBuilder k a
finishB :: MapBuilder k a -> Map k a

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b k x. (Applicative f, Monad f) => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b k x y. Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f k _ x</tt>.
lmapWhenMissing :: forall b a (f :: Type -> Type) k x. (b -> a) -> WhenMissing f k a x -> WhenMissing f k b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k _ y z</tt>.
contramapFirstWhenMatched :: forall b a (f :: Type -> Type) k y z. (b -> a) -> WhenMatched f k a y z -> WhenMatched f k b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k x _ z</tt>.
contramapSecondWhenMatched :: forall b a (f :: Type -> Type) k x z. (b -> a) -> WhenMatched f k x a z -> WhenMatched f k x b z

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>, using only a
--   'Functor f' constraint.
mapGentlyWhenMissing :: forall (f :: Type -> Type) a b k x. Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x</tt>, using only a
--   'Functor f' constraint.
mapGentlyWhenMatched :: forall (f :: Type -> Type) a b k x y. Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Base.Applicative (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Applicative (Data.Map.Internal.WhenMissing f k x)
instance Data.Bifoldable.Bifoldable Data.Map.Internal.Map
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Control.Category.Category (Data.Map.Internal.WhenMatched f k x)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Control.Category.Category (Data.Map.Internal.WhenMissing f k)
instance (GHC.Internal.Data.Data.Data k, GHC.Internal.Data.Data.Data a, GHC.Internal.Classes.Ord k) => GHC.Internal.Data.Data.Data (Data.Map.Internal.Map k a)
instance GHC.Internal.Classes.Eq k => Data.Functor.Classes.Eq1 (Data.Map.Internal.Map k)
instance Data.Functor.Classes.Eq2 Data.Map.Internal.Map
instance (GHC.Internal.Classes.Eq k, GHC.Internal.Classes.Eq a) => GHC.Internal.Classes.Eq (Data.Map.Internal.Map k a)
instance GHC.Internal.Data.Foldable.Foldable (Data.Map.Internal.Map k)
instance GHC.Internal.Base.Functor (Data.Map.Internal.Map k)
instance GHC.Internal.Base.Functor f => GHC.Internal.Base.Functor (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Functor (Data.Map.Internal.WhenMissing f k x)
instance GHC.Internal.Classes.Ord k => GHC.Internal.IsList.IsList (Data.Map.Internal.Map k v)
instance (GHC.Internal.TH.Lift.Lift k, GHC.Internal.TH.Lift.Lift a) => GHC.Internal.TH.Lift.Lift (Data.Map.Internal.Map k a)
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Base.Monad (Data.Map.Internal.WhenMatched f k x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Monad (Data.Map.Internal.WhenMissing f k x)
instance GHC.Internal.Classes.Ord k => GHC.Internal.Base.Monoid (Data.Map.Internal.Map k v)
instance Control.DeepSeq.NFData k => Control.DeepSeq.NFData1 (Data.Map.Internal.Map k)
instance Control.DeepSeq.NFData2 Data.Map.Internal.Map
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Map.Internal.Map k a)
instance GHC.Internal.Classes.Ord k => Data.Functor.Classes.Ord1 (Data.Map.Internal.Map k)
instance Data.Functor.Classes.Ord2 Data.Map.Internal.Map
instance (GHC.Internal.Classes.Ord k, GHC.Internal.Classes.Ord v) => GHC.Internal.Classes.Ord (Data.Map.Internal.Map k v)
instance (GHC.Internal.Classes.Ord k, GHC.Internal.Read.Read k) => Data.Functor.Classes.Read1 (Data.Map.Internal.Map k)
instance (GHC.Internal.Classes.Ord k, GHC.Internal.Read.Read k, GHC.Internal.Read.Read e) => GHC.Internal.Read.Read (Data.Map.Internal.Map k e)
instance GHC.Internal.Classes.Ord k => GHC.Internal.Base.Semigroup (Data.Map.Internal.Map k v)
instance GHC.Internal.Show.Show k => Data.Functor.Classes.Show1 (Data.Map.Internal.Map k)
instance Data.Functor.Classes.Show2 Data.Map.Internal.Map
instance (GHC.Internal.Show.Show k, GHC.Internal.Show.Show a) => GHC.Internal.Show.Show (Data.Map.Internal.Map k a)
instance GHC.Internal.Data.Traversable.Traversable (Data.Map.Internal.Map k)


-- | This module defines an API for writing functions that merge two maps.
--   The key functions are <a>merge</a> and <a>mergeA</a>. Each of these
--   can be used with several different "merge tactics".
--   
--   The <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
--   and strict modules. Only the choice of merge tactics determines
--   strictness. If you use <a>mapMissing</a> from
--   <a>Data.Map.Merge.Strict</a> then the results will be forced before
--   they are inserted. If you use <a>mapMissing</a> from this module then
--   they will not.
--   
--   <h2>Efficiency note</h2>
--   
--   The <a>Category</a>, <a>Applicative</a>, and <a>Monad</a> instances
--   for <a>WhenMissing</a> tactics are included because they are valid.
--   However, they are inefficient in many cases and should usually be
--   avoided. The instances for <a>WhenMatched</a> tactics should not pose
--   any major efficiency problems.
module Data.Map.Merge.Lazy

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; Maybe z
--   </tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt;
--   Maybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge preserveMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge preserveMissing preserveMissing (zipWithMaybeMatched $ \ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (mapMissing f) (mapMissing g) (zipWithMatched h)
--   </pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
--                       -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
--                  -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) k x y. Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) k x. Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMissing f k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
--   </tt>.
data WhenMissing (f :: Type -> Type) k x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
--   (Maybe z) </tt>.
data WhenMatched (f :: Type -> Type) k x y z

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <tt>mergeA</tt> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b k x. (Applicative f, Monad f) => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b k x y. Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f k _ x</tt>.
lmapWhenMissing :: forall b a (f :: Type -> Type) k x. (b -> a) -> WhenMissing f k a x -> WhenMissing f k b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k _ y z</tt>.
contramapFirstWhenMatched :: forall b a (f :: Type -> Type) k y z. (b -> a) -> WhenMatched f k a y z -> WhenMatched f k b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f k x _ z</tt>.
contramapSecondWhenMatched :: forall b a (f :: Type -> Type) k x z. (b -> a) -> WhenMatched f k x a z -> WhenMatched f k x b z

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

module Data.Map.Internal.Debug

-- | &lt;math&gt;. Show the tree that implements the map. The tree is shown
--   in a compressed, hanging format. See <a>showTreeWith</a>.
showTree :: (Show k, Show a) => Map k a -> String

-- | &lt;math&gt;. The expression (<tt><a>showTreeWith</a> showelem hang
--   wide map</tt>) shows the tree that implements the map. Elements are
--   shown using the <tt>showElem</tt> function. If <tt>hang</tt> is
--   <a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
--   
--   <pre>
--   Map&gt; let t = fromDistinctAscList [(x,()) | x &lt;- [1..5]]
--   Map&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True False t
--   (4,())
--   +--(2,())
--   |  +--(1,())
--   |  +--(3,())
--   +--(5,())
--   
--   Map&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) True True t
--   (4,())
--   |
--   +--(2,())
--   |  |
--   |  +--(1,())
--   |  |
--   |  +--(3,())
--   |
--   +--(5,())
--   
--   Map&gt; putStrLn $ showTreeWith (\k x -&gt; show (k,x)) False True t
--   +--(5,())
--   |
--   (4,())
--   |
--   |  +--(3,())
--   |  |
--   +--(2,())
--      |
--      +--(1,())
--   </pre>
showTreeWith :: (k -> a -> String) -> Bool -> Bool -> Map k a -> String
showsTree :: (k -> a -> String) -> Bool -> [String] -> [String] -> Map k a -> ShowS
showsTreeHang :: (k -> a -> String) -> Bool -> [String] -> Map k a -> ShowS
showWide :: Bool -> [String] -> String -> String
showsBars :: [String] -> ShowS
node :: String
withBar :: [String] -> [String]
withEmpty :: [String] -> [String]

-- | &lt;math&gt;. Test if the internal map structure is valid.
--   
--   <pre>
--   valid (fromAscList [(3,"b"), (5,"a")]) == True
--   valid (fromAscList [(5,"a"), (3,"b")]) == False
--   </pre>
valid :: Ord k => Map k a -> Bool

-- | Test if the keys are ordered correctly.
ordered :: Ord a => Map a b -> Bool

-- | Test if a map obeys the balance invariants.
balanced :: Map k a -> Bool

-- | Test if each node of a map reports its size correctly.
validsize :: Map a b -> Bool


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Maps (strict interface internals)</h1>
--   
--   The <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>k</tt> to values of type
--   <tt>v</tt>.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Map</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
module Data.Map.Strict.Internal

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a
Bin :: Size -> k -> a -> Map k a -> Map k a -> Map k a
Tip :: Map k a
type Size = Int

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
--   </pre>
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | &lt;math&gt;. The number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: Map k a -> Int

-- | &lt;math&gt;. Is the key a member of the map? See also
--   <a>notMember</a>.
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map? See also
--   <a>member</a>.
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Look up the value at a key in the map.
--   
--   The function will return the corresponding value as <tt>(<a>Just</a>
--   value)</tt>, or <a>Nothing</a> if the key isn't in the map.
--   
--   An example of using <tt>lookup</tt>:
--   
--   <pre>
--   import Prelude hiding (lookup)
--   import Data.Map
--   
--   employeeDept = fromList([("John","Sales"), ("Bob","IT")])
--   deptCountry = fromList([("IT","USA"), ("Sales","France")])
--   countryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
--   
--   employeeCurrency :: String -&gt; Maybe String
--   employeeCurrency name = do
--       dept &lt;- lookup name employeeDept
--       country &lt;- lookup dept deptCountry
--       lookup country countryCurrency
--   
--   main = do
--       putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
--       putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
--   </pre>
--   
--   The output of this program:
--   
--   <pre>
--   John's currency: Just "Euro"
--   Pete's currency: Nothing
--   </pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns default value
--   <tt>def</tt> when the key is not in the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | &lt;math&gt;. A map with a single element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: k -> a -> Map k a

-- | &lt;math&gt;. Insert a new key and value in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
--   <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining new value and old
--   value. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert the pair <tt>(key, f
--   new_value old_value)</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining key, new value and old
--   value. <tt><a>insertWithKey</a> f key value mp</tt> will insert the
--   pair (key, value) into <tt>mp</tt> if key does not exist in the map.
--   If the key does exist, the function will insert the pair <tt>(key,f
--   key new_value old_value)</tt>. Note that the key passed to f is the
--   same key passed to <a>insertWithKey</a>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Combines insert operation with old value retrieval. The
--   expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a pair
--   where the first element is equal to (<tt><a>lookup</a> k map</tt>) and
--   the second element equal to (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | &lt;math&gt;. Update a value at a specific key with the result of the
--   provided function. When the key is not a member of the map, the
--   original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>updateWithKey</a> f k map</tt>)
--   updates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
--   (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Look up and update. See also <a>updateWithKey</a>. This
--   function returns the changed value, if it is updated. Returns the
--   original key value if the map entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in a <a>Map</a>. In
--   short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
--   m)</tt>.
--   
--   <pre>
--   let f _ = Nothing
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   
--   let f _ = Just "c"
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
--   </pre>
--   
--   Note that <tt><a>adjust</a> = alter . fmap</tt>.
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in a
--   <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a> f k
--   m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map. When used with
--   trivial functors like <a>Identity</a> and <a>Const</a>, it is often
--   slightly slower than more specialized combinators like <a>lookup</a>
--   and <a>insert</a>. However, when the functor is non-trivial and key
--   comparison is not particularly cheap, it is the fastest way.
--   
--   Note on rewrite rules:
--   
--   This module includes GHC rewrite rules to optimize <a>alterF</a> for
--   the <a>Const</a> and <a>Identity</a> functors. In general, these rules
--   improve performance. The sole exception is that when using
--   <a>Identity</a>, deleting a key that is already absent takes longer
--   than it would without the rules. If you expect this to occur a very
--   large fraction of the time, you might consider using a private copy of
--   the <a>Identity</a> type.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | &lt;math&gt;. The expression (<tt><a>union</a> t1 t2</tt>) takes the
--   left-biased union of <tt>t1</tt> and <tt>t2</tt>. It prefers
--   <tt>t1</tt> when duplicate keys are encountered, i.e.
--   (<tt><a>union</a> == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
--   <a>union</a> <a>empty</a></tt>).
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: (Foldable f, Ord k) => f (Map k a) -> Map k a

-- | The union of a list of maps, with a combining operation:
--   (<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
--   <a>empty</a></tt>).
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: (Foldable f, Ord k) => (a -> a -> a) -> f (Map k a) -> Map k a

-- | &lt;math&gt;. Difference of two maps. Return elements of the first map
--   not existing in the second map.
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Difference with a combining function. When two equal
--   keys are encountered, the combining function is applied to the values
--   of these keys. If it returns <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection of two maps. Return data in the first map
--   for the keys existing in both maps. (<tt><a>intersection</a> m1 m2 ==
--   <a>intersectionWith</a> <a>const</a> m1 m2</tt>).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e., their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord k => Map k a -> Map k b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.Map.Strict</a> exposed a version
--   of <a>compose</a> that forced the values of the output <a>Map</a>.
--   This version does not force these values.
--   
--   <h4><b>Note on complexity</b></h4>
--   
--   This function is asymptotically optimal. Given <tt>n :: Map a b, m ::
--   Map b c</tt>, the composition essentially maps each <tt>a</tt> in
--   <tt>n</tt> to <tt>Maybe c</tt>, since the composed lookup yields
--   either one of the <tt>c</tt> in <tt>m</tt> or <tt>Nothing</tt>. The
--   number of possible such mappings is &lt;math&gt;. We now follow a
--   similar reasoning to the one for <a>sorting</a>. To distinguish
--   between &lt;math&gt; possible values, we need &lt;math&gt; bits. Thus,
--   we have a lower bound of &lt;math&gt; bits. <tt>Map</tt> lookups are
--   comparison-based, and each comparison gives us at most one bit of
--   information: in the worst case we'll always be left with at least half
--   of the remaining possible values, meaning we need at least as many
--   comparisons as we need bits.
compose :: Ord b => Map b c -> Map a b -> Map a c

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; Maybe z
--   </tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt;
--   Maybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge preserveMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge preserveMissing preserveMissing (zipWithMaybeMatched $ \ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (mapMissing f) (mapMissing g) (zipWithMatched h)
--   </pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
--                       -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
--                  -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) k x y. Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Force the entries whose keys are missing from the other map and
--   otherwise preserve them unchanged.
--   
--   <pre>
--   preserveMissing' :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing' = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just $! x)
--   </pre>
--   
--   but <tt>preserveMissing'</tt> is quite a bit faster.
preserveMissing' :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) k x. Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMissing f k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
--   </tt>.
data WhenMissing (f :: Type -> Type) k x y
WhenMissing :: (Map k x -> f (Map k y)) -> (k -> x -> f (Maybe y)) -> WhenMissing (f :: Type -> Type) k x y
[missingSubtree] :: WhenMissing (f :: Type -> Type) k x y -> Map k x -> f (Map k y)
[missingKey] :: WhenMissing (f :: Type -> Type) k x y -> k -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
--   (Maybe z) </tt>.
newtype WhenMatched (f :: Type -> Type) k x y z
WhenMatched :: (k -> x -> y -> f (Maybe z)) -> WhenMatched (f :: Type -> Type) k x y z
[matchedKey] :: WhenMatched (f :: Type -> Type) k x y z -> k -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <tt>mergeA</tt> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: Applicative f => (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b k x. Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b k x y. Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | &lt;math&gt;. An unsafe universal combining function.
--   
--   <b>Warning</b>: This function can produce corrupt maps and its results
--   may depend on the internal structures of its inputs. Users should
--   prefer <a>merge</a> or <a>mergeA</a>.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>Map</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
--   &lt;$&gt; <a>traverse</a> (\(k, v) -&gt; (v' -&gt; v' `seq` (k,v'))
--   &lt;$&gt; f k v) (<a>toList</a> m)</tt> That is, it behaves much like
--   a regular <a>traverse</a> except that the traversing function also has
--   access to the key associated with a value and the values are forced
--   before they are installed in the result map.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | &lt;math&gt;. The function <a>mapAccum</a> threads an accumulating
--   argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumWithKey</a> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumRWithKey</a> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>. The value at the greater of the two
--   original keys is used as the first argument to <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   valid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
--   valid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
--   </pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: Map k a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: Map k a -> [k]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Return all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: Map k a -> [(k, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
--   keysSet empty == Data.Set.empty
--   </pre>
keysSet :: Map k a -> Set k

-- | &lt;math&gt;. The set of all elements of the map contained in
--   <a>Arg</a>s.
--   
--   <pre>
--   argSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [Arg 3 "b",Arg 5 "a"]
--   argSet empty == Data.Set.empty
--   </pre>
argSet :: Map k a -> Set (Arg k a)

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.Set.empty == empty
--   </pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | &lt;math&gt;. Build a map from a set of elements contained inside
--   <a>Arg</a>s.
--   
--   <pre>
--   fromArgSet (Data.Set.fromList [Arg 3 "aaa", Arg 5 "aaaaa"]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromArgSet Data.Set.empty == empty
--   </pre>
fromArgSet :: Set (Arg k a) -> Map k a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Build a map from a list of key/value pairs. See also
--   <a>fromAscList</a>. If the list contains more than one value for the
--   same key, the last value for the key is retained.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Build a map from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
--   valid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
--   valid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
--   </pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
--   fromDescList [(5,"a"), (5,"b"), (3,"a")] == fromList [(3, "b"), (5, "b")]
--   valid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
--   valid (fromDistinctDescList [(5,"a"), (3,"b"), (3,"a")]) == False
--   </pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Filter all values that satisfy the predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys that satisfy the predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys/values that satisfy the predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Restrict a <a>Map</a> to only those keys found in a
--   <a>Set</a>.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   m `restrictKeys` s = m <a>`intersection`</a> <a>fromSet</a> (const ()) s
--   </pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Remove all keys in a <a>Set</a> from a <a>Map</a>.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   m `withoutKeys` s = m <a>`difference`</a> <a>fromSet</a> (const ()) s
--   </pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all keys
--   <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j &gt;= p
--   k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partitionWithKey (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first key and to fail after
--   the last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller than
--   <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>splitLookup</a> k map</tt>)
--   splits a map just like <a>split</a> but also returns <tt><a>lookup</a>
--   k map</tt>.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | &lt;math&gt;. This function is defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f t1 t2</tt>)
--   returns <a>True</a> if all keys in <tt>t1</tt> are in tree
--   <tt>t2</tt>, and when <tt>f</tt> returns <a>True</a> when applied to
--   their respective values. For example, the following expressions are
--   all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
--   </pre>
--   
--   Note that <tt>isSubmapOfBy (_ _ -&gt; True) m1 m2</tt> tests whether
--   all the keys in <tt>m1</tt> are also keys in <tt>m2</tt>.
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Look up the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   
--   <pre>
--   isJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
--   fromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
--   fromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
--   isJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
--   </pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   Calls <a>error</a> when the key is not a <a>member</a> of the map.
--   
--   <pre>
--   findIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   findIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
--   findIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
--   findIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   </pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
--   elemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
elemAt :: Int -> Map k a -> (k, a)

-- | &lt;math&gt;. Update the element at <i>index</i>. Calls <a>error</a>
--   when an invalid index is used.
--   
--   <pre>
--   updateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
--   updateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
--   updateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   updateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   updateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   deleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   deleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
--   deleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
--   </pre>
deleteAt :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Take a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Drop a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Split a map at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
--   lookupMin empty = Nothing
--   </pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
--   lookupMax empty = Nothing
--   </pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   findMin empty                            Error: empty map has no minimal element
--   </pre>
findMin :: Map k a -> (k, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMax (fromList [(5,"a"), (3,"b")]) == (5,"a")
--   findMax empty                            Error: empty map has no maximal element
--   </pre>
findMax :: Map k a -> (k, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
--   deleteMin empty == empty
--   </pre>
deleteMin :: Map k a -> Map k a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
--   deleteMax empty == empty
--   </pre>
deleteMax :: Map k a -> Map k a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
--   deleteFindMin empty                                      Error: can not return the minimal element of an empty map
--   </pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
--   deleteFindMax empty                                      Error: can not return the maximal element of an empty map
--   </pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Retrieves the value associated with minimal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   minView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
--   minView empty == Nothing
--   </pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the value associated with maximal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   maxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
--   maxView empty == Nothing
--   </pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Test if the internal map structure is valid.
--   
--   <pre>
--   valid (fromAscList [(3,"b"), (5,"a")]) == True
--   valid (fromAscList [(5,"a"), (3,"b")]) == False
--   </pre>
valid :: Ord k => Map k a -> Bool


-- | <h1>Finite Maps (strict interface)</h1>
--   
--   The <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>k</tt> to values of type
--   <tt>v</tt>.
--   
--   Each function in this module is careful to force values before
--   installing them in a <a>Map</a>. This is usually more efficient when
--   laziness is not necessary. When laziness <i>is</i> required, use the
--   functions in <a>Data.Map.Lazy</a>.
--   
--   In particular, the functions in this module obey the following law:
--   
--   <ul>
--   <li>If all values stored in all maps in the arguments are in WHNF,
--   then all values stored in all maps in the results will be in WHNF once
--   those maps are evaluated.</li>
--   </ul>
--   
--   When deciding if this is the correct data structure to use, consider:
--   
--   <ul>
--   <li>If you are using <a>Int</a> keys, you will get much better
--   performance for most operations using <a>Data.IntMap.Strict</a>.</li>
--   <li>If you don't care about ordering, consider use
--   <tt>Data.HashMap.Strict</tt> from the <a>unordered-containers</a>
--   package instead.</li>
--   </ul>
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.Map.Strict (Map)
--   import qualified Data.Map.Strict as Map
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Warning</h2>
--   
--   The size of a <a>Map</a> must not exceed <tt>maxBound::Int</tt>.
--   Violation of this condition is not detected and if the size limit is
--   exceeded, its behaviour is undefined.
--   
--   The <a>Map</a> type is shared between the lazy and strict modules,
--   meaning that the same <a>Map</a> value can be passed to functions in
--   both modules. This means that the <a>Functor</a>, <a>Traversable</a>
--   and <a>Data</a> instances are the same as for the <a>Data.Map.Lazy</a>
--   module, so if they are used the resulting maps may contain suspended
--   values (thunks).
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Map</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   The time complexity is given for each operation in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map.
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> take
--   &lt;math&gt; time.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
--   
--   Benchmarks comparing <a>Data.Map.Strict</a> with other dictionary
--   implementations can be found at
--   <a>https://github.com/haskell-perf/dictionaries</a>.
module Data.Map.Strict

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | &lt;math&gt;. A map with a single element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: k -> a -> Map k a

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.Set.empty == empty
--   </pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | &lt;math&gt;. Build a map from a set of elements contained inside
--   <a>Arg</a>s.
--   
--   <pre>
--   fromArgSet (Data.Set.fromList [Arg 3 "aaa", Arg 5 "aaaaa"]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromArgSet Data.Set.empty == empty
--   </pre>
fromArgSet :: Set (Arg k a) -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs. See also
--   <a>fromAscList</a>. If the list contains more than one value for the
--   same key, the last value for the key is retained.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
--   valid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
--   valid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
--   </pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
--   fromDescList [(5,"a"), (5,"b"), (3,"a")] == fromList [(3, "b"), (5, "b")]
--   valid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
--   valid (fromDistinctDescList [(5,"a"), (3,"b"), (3,"a")]) == False
--   </pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Insert a new key and value in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
--   <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining new value and old
--   value. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert the pair <tt>(key, f
--   new_value old_value)</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining key, new value and old
--   value. <tt><a>insertWithKey</a> f key value mp</tt> will insert the
--   pair (key, value) into <tt>mp</tt> if key does not exist in the map.
--   If the key does exist, the function will insert the pair <tt>(key,f
--   key new_value old_value)</tt>. Note that the key passed to f is the
--   same key passed to <a>insertWithKey</a>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Combines insert operation with old value retrieval. The
--   expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a pair
--   where the first element is equal to (<tt><a>lookup</a> k map</tt>) and
--   the second element equal to (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | &lt;math&gt;. Update a value at a specific key with the result of the
--   provided function. When the key is not a member of the map, the
--   original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>updateWithKey</a> f k map</tt>)
--   updates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
--   (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Look up and update. See also <a>updateWithKey</a>. This
--   function returns the changed value, if it is updated. Returns the
--   original key value if the map entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in a <a>Map</a>. In
--   short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
--   m)</tt>.
--   
--   <pre>
--   let f _ = Nothing
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   
--   let f _ = Just "c"
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
--   </pre>
--   
--   Note that <tt><a>adjust</a> = alter . fmap</tt>.
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in a
--   <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a> f k
--   m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map. When used with
--   trivial functors like <a>Identity</a> and <a>Const</a>, it is often
--   slightly slower than more specialized combinators like <a>lookup</a>
--   and <a>insert</a>. However, when the functor is non-trivial and key
--   comparison is not particularly cheap, it is the fastest way.
--   
--   Note on rewrite rules:
--   
--   This module includes GHC rewrite rules to optimize <a>alterF</a> for
--   the <a>Const</a> and <a>Identity</a> functors. In general, these rules
--   improve performance. The sole exception is that when using
--   <a>Identity</a>, deleting a key that is already absent takes longer
--   than it would without the rules. If you expect this to occur a very
--   large fraction of the time, you might consider using a private copy of
--   the <a>Identity</a> type.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | &lt;math&gt;. Look up the value at a key in the map.
--   
--   The function will return the corresponding value as <tt>(<a>Just</a>
--   value)</tt>, or <a>Nothing</a> if the key isn't in the map.
--   
--   An example of using <tt>lookup</tt>:
--   
--   <pre>
--   import Prelude hiding (lookup)
--   import Data.Map
--   
--   employeeDept = fromList([("John","Sales"), ("Bob","IT")])
--   deptCountry = fromList([("IT","USA"), ("Sales","France")])
--   countryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
--   
--   employeeCurrency :: String -&gt; Maybe String
--   employeeCurrency name = do
--       dept &lt;- lookup name employeeDept
--       country &lt;- lookup dept deptCountry
--       lookup country countryCurrency
--   
--   main = do
--       putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
--       putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
--   </pre>
--   
--   The output of this program:
--   
--   <pre>
--   John's currency: Just "Euro"
--   Pete's currency: Nothing
--   </pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
--   </pre>
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns default value
--   <tt>def</tt> when the key is not in the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | &lt;math&gt;. Is the key a member of the map? See also
--   <a>notMember</a>.
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map? See also
--   <a>member</a>.
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | &lt;math&gt;. The number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: Map k a -> Int

-- | &lt;math&gt;. The expression (<tt><a>union</a> t1 t2</tt>) takes the
--   left-biased union of <tt>t1</tt> and <tt>t2</tt>. It prefers
--   <tt>t1</tt> when duplicate keys are encountered, i.e.
--   (<tt><a>union</a> == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
--   <a>union</a> <a>empty</a></tt>).
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: (Foldable f, Ord k) => f (Map k a) -> Map k a

-- | The union of a list of maps, with a combining operation:
--   (<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
--   <a>empty</a></tt>).
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: (Foldable f, Ord k) => (a -> a -> a) -> f (Map k a) -> Map k a

-- | &lt;math&gt;. Difference of two maps. Return elements of the first map
--   not existing in the second map.
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | &lt;math&gt;. Difference with a combining function. When two equal
--   keys are encountered, the combining function is applied to the values
--   of these keys. If it returns <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection of two maps. Return data in the first map
--   for the keys existing in both maps. (<tt><a>intersection</a> m1 m2 ==
--   <a>intersectionWith</a> <a>const</a> m1 m2</tt>).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e., their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord k => Map k a -> Map k b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.Map.Strict</a> exposed a version
--   of <a>compose</a> that forced the values of the output <a>Map</a>.
--   This version does not force these values.
--   
--   <h4><b>Note on complexity</b></h4>
--   
--   This function is asymptotically optimal. Given <tt>n :: Map a b, m ::
--   Map b c</tt>, the composition essentially maps each <tt>a</tt> in
--   <tt>n</tt> to <tt>Maybe c</tt>, since the composed lookup yields
--   either one of the <tt>c</tt> in <tt>m</tt> or <tt>Nothing</tt>. The
--   number of possible such mappings is &lt;math&gt;. We now follow a
--   similar reasoning to the one for <a>sorting</a>. To distinguish
--   between &lt;math&gt; possible values, we need &lt;math&gt; bits. Thus,
--   we have a lower bound of &lt;math&gt; bits. <tt>Map</tt> lookups are
--   comparison-based, and each comparison gives us at most one bit of
--   information: in the worst case we'll always be left with at least half
--   of the remaining possible values, meaning we need at least as many
--   comparisons as we need bits.
compose :: Ord b => Map b c -> Map a b -> Map a c

-- | &lt;math&gt;. An unsafe universal combining function.
--   
--   <b>Warning</b>: This function can produce corrupt maps and its results
--   may depend on the internal structures of its inputs. Users should
--   prefer <a>merge</a> or <a>mergeA</a>.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>Map</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
--   &lt;$&gt; <a>traverse</a> (\(k, v) -&gt; (v' -&gt; v' `seq` (k,v'))
--   &lt;$&gt; f k v) (<a>toList</a> m)</tt> That is, it behaves much like
--   a regular <a>traverse</a> except that the traversing function also has
--   access to the key associated with a value and the values are forced
--   before they are installed in the result map.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | &lt;math&gt;. The function <a>mapAccum</a> threads an accumulating
--   argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumWithKey</a> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumRWithKey</a> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>. The value at the greater of the two
--   original keys is used as the first argument to <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   valid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
--   valid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
--   </pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: Map k a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: Map k a -> [k]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Return all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: Map k a -> [(k, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
--   keysSet empty == Data.Set.empty
--   </pre>
keysSet :: Map k a -> Set k

-- | &lt;math&gt;. The set of all elements of the map contained in
--   <a>Arg</a>s.
--   
--   <pre>
--   argSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [Arg 3 "b",Arg 5 "a"]
--   argSet empty == Data.Set.empty
--   </pre>
argSet :: Map k a -> Set (Arg k a)

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Filter all values that satisfy the predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys that satisfy the predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys/values that satisfy the predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Restrict a <a>Map</a> to only those keys found in a
--   <a>Set</a>.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   m `restrictKeys` s = m <a>`intersection`</a> <a>fromSet</a> (const ()) s
--   </pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Remove all keys in a <a>Set</a> from a <a>Map</a>.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   m `withoutKeys` s = m <a>`difference`</a> <a>fromSet</a> (const ()) s
--   </pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all keys
--   <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j &gt;= p
--   k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partitionWithKey (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first key and to fail after
--   the last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller than
--   <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>splitLookup</a> k map</tt>)
--   splits a map just like <a>split</a> but also returns <tt><a>lookup</a>
--   k map</tt>.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | &lt;math&gt;. This function is defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f t1 t2</tt>)
--   returns <a>True</a> if all keys in <tt>t1</tt> are in tree
--   <tt>t2</tt>, and when <tt>f</tt> returns <a>True</a> when applied to
--   their respective values. For example, the following expressions are
--   all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
--   </pre>
--   
--   Note that <tt>isSubmapOfBy (_ _ -&gt; True) m1 m2</tt> tests whether
--   all the keys in <tt>m1</tt> are also keys in <tt>m2</tt>.
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Look up the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   
--   <pre>
--   isJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
--   fromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
--   fromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
--   isJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
--   </pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   Calls <a>error</a> when the key is not a <a>member</a> of the map.
--   
--   <pre>
--   findIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   findIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
--   findIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
--   findIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   </pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
--   elemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
elemAt :: Int -> Map k a -> (k, a)

-- | &lt;math&gt;. Update the element at <i>index</i>. Calls <a>error</a>
--   when an invalid index is used.
--   
--   <pre>
--   updateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
--   updateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
--   updateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   updateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   updateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   deleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   deleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
--   deleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
--   </pre>
deleteAt :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Take a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Drop a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Split a map at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
--   lookupMin empty = Nothing
--   </pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
--   lookupMax empty = Nothing
--   </pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   findMin empty                            Error: empty map has no minimal element
--   </pre>
findMin :: Map k a -> (k, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMax (fromList [(5,"a"), (3,"b")]) == (5,"a")
--   findMax empty                            Error: empty map has no maximal element
--   </pre>
findMax :: Map k a -> (k, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
--   deleteMin empty == empty
--   </pre>
deleteMin :: Map k a -> Map k a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
--   deleteMax empty == empty
--   </pre>
deleteMax :: Map k a -> Map k a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
--   deleteFindMin empty                                      Error: can not return the minimal element of an empty map
--   </pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
--   deleteFindMax empty                                      Error: can not return the maximal element of an empty map
--   </pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Retrieves the value associated with minimal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   minView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
--   minView empty == Nothing
--   </pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the value associated with maximal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   maxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
--   maxView empty == Nothing
--   </pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Test if the internal map structure is valid.
--   
--   <pre>
--   valid (fromAscList [(3,"b"), (5,"a")]) == True
--   valid (fromAscList [(5,"a"), (3,"b")]) == False
--   </pre>
valid :: Ord k => Map k a -> Bool


-- | This module defines an API for writing functions that merge two maps.
--   The key functions are <a>merge</a> and <a>mergeA</a>. Each of these
--   can be used with several different "merge tactics".
--   
--   The <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
--   and strict modules. Only the choice of merge tactics determines
--   strictness. If you use <a>mapMissing</a> from this module then the
--   results will be forced before they are inserted. If you use
--   <a>mapMissing</a> from <a>Data.Map.Merge.Lazy</a> then they will not.
--   
--   <h2><a>preserveMissing</a> inconsistency</h2>
--   
--   For historical reasons, the preserved values are /<i>not</i>/ forced.
--   To force them, use <a>preserveMissing'</a>.
--   
--   <h2>Efficiency note</h2>
--   
--   The <a>Category</a>, <a>Applicative</a>, and <a>Monad</a> instances
--   for <a>WhenMissing</a> tactics are included because they are valid.
--   However, they are inefficient in many cases and should usually be
--   avoided. The instances for <a>WhenMatched</a> tactics should not pose
--   any major efficiency problems.
module Data.Map.Merge.Strict

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMissing k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; Maybe z
--   </tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt> SimpleWhenMatched k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt;
--   Maybe z </tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge preserveMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge preserveMissing preserveMissing (zipWithMaybeMatched $ \ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (mapMissing f) (mapMissing g) (zipWithMatched h)
--   </pre>
merge :: Ord k => SimpleWhenMissing k a c -> SimpleWhenMissing k b c -> SimpleWhenMatched k a b c -> Map k a -> Map k b -> Map k c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
--                       -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> Maybe z) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
--                  -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) k x y z. Applicative f => (k -> x -> y -> z) -> WhenMatched f k x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> Maybe y) -> WhenMissing f k x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) k x y. Applicative f => WhenMissing f k x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Force the entries whose keys are missing from the other map and
--   otherwise preserve them unchanged.
--   
--   <pre>
--   preserveMissing' :: SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   preserveMissing' = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just $! x)
--   </pre>
--   
--   but <tt>preserveMissing'</tt> is quite a bit faster.
preserveMissing' :: forall (f :: Type -> Type) k x. Applicative f => WhenMissing f k x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) k x y. Applicative f => (k -> x -> y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing k x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) k x. Applicative f => (k -> x -> Bool) -> WhenMissing f k x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMissing f k x z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; f (Maybe z)
--   </tt>.
data WhenMissing (f :: Type -> Type) k x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt> WhenMatched f k x y z </tt> is an abstract
--   representation of a function of type <tt> k -&gt; x -&gt; y -&gt; f
--   (Maybe z) </tt>.
data WhenMatched (f :: Type -> Type) k x y z

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <tt>mergeA</tt> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: (Applicative f, Ord k) => WhenMissing f k a c -> WhenMissing f k b c -> WhenMatched f k a b c -> Map k a -> Map k b -> f (Map k c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: Applicative f => (k -> x -> y -> f (Maybe z)) -> WhenMatched f k x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (k -> x -> y -> f z) -> WhenMatched f k x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (k -> x -> f (Maybe y)) -> WhenMissing f k x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (k -> x -> f y) -> WhenMissing f k x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (k -> x -> f Bool) -> WhenMissing f k x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b k x. Functor f => (a -> b) -> WhenMissing f k x a -> WhenMissing f k x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b k x y. Functor f => (a -> b) -> WhenMatched f k x y a -> WhenMatched f k x y b

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f k x y z</tt> and <tt>k -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f k x y z -> k -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f k x y</tt> and <tt>k -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f k x y -> k -> x -> f (Maybe y)


-- | <h1>Finite Maps (lazy interface)</h1>
--   
--   The <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>k</tt> to values of type
--   <tt>v</tt>. A <a>Map</a> is strict in its keys but lazy in its values.
--   
--   The functions in <a>Data.Map.Strict</a> are careful to force values
--   before installing them in a <a>Map</a>. This is usually more efficient
--   in cases where laziness is not essential. The functions in this module
--   do not do so.
--   
--   When deciding if this is the correct data structure to use, consider:
--   
--   <ul>
--   <li>If you are using <a>Int</a> keys, you will get much better
--   performance for most operations using <a>Data.IntMap.Lazy</a>.</li>
--   <li>If you don't care about ordering, consider using
--   <tt>Data.HashMap.Lazy</tt> from the <a>unordered-containers</a>
--   package instead.</li>
--   </ul>
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.Map.Lazy (Map)
--   import qualified Data.Map.Lazy as Map
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Warning</h2>
--   
--   The size of a <a>Map</a> must not exceed <tt><a>maxBound</a> ::
--   <a>Int</a></tt>. Violation of this condition is not detected and if
--   the size limit is exceeded, its behaviour is undefined.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Map</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   The time complexity is given for each operation in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map.
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> take
--   &lt;math&gt; time.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
--   
--   Benchmarks comparing <a>Data.Map.Lazy</a> with other dictionary
--   implementations can be found at
--   <a>https://github.com/haskell-perf/dictionaries</a>.
module Data.Map.Lazy

-- | A Map from keys <tt>k</tt> to values <tt>a</tt>.
data Map k a

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | &lt;math&gt;. A map with a single element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: k -> a -> Map k a

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.Set.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.Set.empty == empty
--   </pre>
fromSet :: (k -> a) -> Set k -> Map k a

-- | &lt;math&gt;. Build a map from a set of elements contained inside
--   <a>Arg</a>s.
--   
--   <pre>
--   fromArgSet (Data.Set.fromList [Arg 3 "aaa", Arg 5 "aaaaa"]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromArgSet Data.Set.empty == empty
--   </pre>
fromArgSet :: Set (Arg k a) -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs. See also
--   <a>fromAscList</a>. If the list contains more than one value for the
--   same key, the last value for the key is retained.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: Ord k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   If the keys are in non-decreasing order, this function takes
--   &lt;math&gt; time.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True
--   valid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromAscListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True
--   valid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from an ascending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctAscList [(3,"b"), (5,"a")])          == True
--   valid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
--   </pre>
fromDistinctAscList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescList [(5,"a"), (3,"b")]          == fromList [(3, "b"), (5, "a")]
--   fromDescList [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "b")]
--   valid (fromDescList [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
fromDescList :: Eq k => [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "ba")]
--   valid (fromDescListWith (++) [(5,"a"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWith :: Eq k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list in linear time with a
--   combining function for equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-increasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2
--   fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")] == fromList [(3, "b"), (5, "5:b5:ba")]
--   valid (fromDescListWithKey f [(5,"a"), (5,"b"), (5,"b"), (3,"b")]) == True
--   valid (fromDescListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromDescListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | &lt;math&gt;. Build a map from a descending list of distinct elements
--   in linear time.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctDescList [(5,"a"), (3,"b")] == fromList [(3, "b"), (5, "a")]
--   valid (fromDistinctDescList [(5,"a"), (3,"b")])          == True
--   valid (fromDistinctDescList [(5,"a"), (5,"b"), (3,"b")]) == False
--   </pre>
fromDistinctDescList :: [(k, a)] -> Map k a

-- | &lt;math&gt;. Insert a new key and value in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value. <a>insert</a> is equivalent to <tt><a>insertWith</a>
--   <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Ord k => k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining new value and old
--   value. <tt><a>insertWith</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert the pair <tt>(key, f
--   new_value old_value)</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Insert with a function, combining key, new value and old
--   value. <tt><a>insertWithKey</a> f key value mp</tt> will insert the
--   pair (key, value) into <tt>mp</tt> if key does not exist in the map.
--   If the key does exist, the function will insert the pair <tt>(key,f
--   key new_value old_value)</tt>. Note that the key passed to f is the
--   same key passed to <a>insertWithKey</a>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | &lt;math&gt;. Combines insert operation with old value retrieval. The
--   expression (<tt><a>insertLookupWithKey</a> f k x map</tt>) is a pair
--   where the first element is equal to (<tt><a>lookup</a> k map</tt>) and
--   the second element equal to (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Ord k => k -> Map k a -> Map k a

-- | &lt;math&gt;. Update a value at a specific key with the result of the
--   provided function. When the key is not a member of the map, the
--   original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: Ord k => (k -> a -> a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: Ord k => (a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>updateWithKey</a> f k map</tt>)
--   updates the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If
--   (<tt>f k x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. Look up and update. See also <a>updateWithKey</a>. This
--   function returns the changed value, if it is updated. Returns the
--   original key value if the map entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "5:new a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: Ord k => (k -> a -> Maybe a) -> k -> Map k a -> (Maybe a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in a <a>Map</a>. In
--   short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a> k
--   m)</tt>.
--   
--   <pre>
--   let f _ = Nothing
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   
--   let f _ = Just "c"
--   alter f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "c")]
--   alter f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "c")]
--   </pre>
--   
--   Note that <tt><a>adjust</a> = alter . fmap</tt>.
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in a
--   <a>Map</a>. In short: <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a> f k
--   m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; Map Int String -&gt; IO (Map Int String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map. When used with
--   trivial functors like <a>Identity</a> and <a>Const</a>, it is often
--   slightly slower than more specialized combinators like <a>lookup</a>
--   and <a>insert</a>. However, when the functor is non-trivial and key
--   comparison is not particularly cheap, it is the fastest way.
--   
--   Note on rewrite rules:
--   
--   This module includes GHC rewrite rules to optimize <a>alterF</a> for
--   the <a>Const</a> and <a>Identity</a> functors. In general, these rules
--   improve performance. The sole exception is that when using
--   <a>Identity</a>, deleting a key that is already absent takes longer
--   than it would without the rules. If you expect this to occur a very
--   large fraction of the time, you might consider using a private copy of
--   the <a>Identity</a> type.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: (Functor f, Ord k) => (Maybe a -> f (Maybe a)) -> k -> Map k a -> f (Map k a)

-- | &lt;math&gt;. Look up the value at a key in the map.
--   
--   The function will return the corresponding value as <tt>(<a>Just</a>
--   value)</tt>, or <a>Nothing</a> if the key isn't in the map.
--   
--   An example of using <tt>lookup</tt>:
--   
--   <pre>
--   import Prelude hiding (lookup)
--   import Data.Map
--   
--   employeeDept = fromList([("John","Sales"), ("Bob","IT")])
--   deptCountry = fromList([("IT","USA"), ("Sales","France")])
--   countryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])
--   
--   employeeCurrency :: String -&gt; Maybe String
--   employeeCurrency name = do
--       dept &lt;- lookup name employeeDept
--       country &lt;- lookup dept deptCountry
--       lookup country countryCurrency
--   
--   main = do
--       putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
--       putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))
--   </pre>
--   
--   The output of this program:
--   
--   <pre>
--   John's currency: Just "Euro"
--   Pete's currency: Nothing
--   </pre>
lookup :: Ord k => k -> Map k a -> Maybe a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 1 == Nothing
--   </pre>
--   
--   <pre>
--   fromList [(5, 'a'), (3, 'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: Ord k => Map k a -> k -> Maybe a
infixl 9 !?

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: Ord k => Map k a -> k -> a
infixl 9 !

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns default value
--   <tt>def</tt> when the key is not in the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: Ord k => a -> k -> Map k a -> a

-- | &lt;math&gt;. Is the key a member of the map? See also
--   <a>notMember</a>.
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map? See also
--   <a>member</a>.
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Ord k => k -> Map k a -> Bool

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Ord k => k -> Map k v -> Maybe (k, v)

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | &lt;math&gt;. The number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: Map k a -> Int

-- | &lt;math&gt;. The expression (<tt><a>union</a> t1 t2</tt>) takes the
--   left-biased union of <tt>t1</tt> and <tt>t2</tt>. It prefers
--   <tt>t1</tt> when duplicate keys are encountered, i.e.
--   (<tt><a>union</a> == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: Ord k => (k -> a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | The union of a list of maps: (<tt><a>unions</a> == <a>foldl</a>
--   <a>union</a> <a>empty</a></tt>).
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: (Foldable f, Ord k) => f (Map k a) -> Map k a

-- | The union of a list of maps, with a combining operation:
--   (<tt><a>unionsWith</a> f == <a>foldl</a> (<a>unionWith</a> f)
--   <a>empty</a></tt>).
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: (Foldable f, Ord k) => (a -> a -> a) -> f (Map k a) -> Map k a

-- | &lt;math&gt;. Difference of two maps. Return elements of the first map
--   not existing in the second map.
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: Ord k => Map k a -> Map k b -> Map k a

-- | Same as <a>difference</a>.
(\\) :: Ord k => Map k a -> Map k b -> Map k a
infixl 9 \\

-- | &lt;math&gt;. Difference with a combining function. When two equal
--   keys are encountered, the combining function is applied to the values
--   of these keys. If it returns <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: Ord k => (a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: Ord k => (k -> a -> b -> Maybe a) -> Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection of two maps. Return data in the first map
--   for the keys existing in both maps. (<tt><a>intersection</a> m1 m2 ==
--   <a>intersectionWith</a> <a>const</a> m1 m2</tt>).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: Ord k => Map k a -> Map k b -> Map k a

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: Ord k => (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: Ord k => Map k a -> Map k a -> Map k a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e., their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   xs <a>`disjoint`</a> ys = null (xs <a>`intersection`</a> ys)
--   </pre>
disjoint :: Ord k => Map k a -> Map k b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.Map.Strict</a> exposed a version
--   of <a>compose</a> that forced the values of the output <a>Map</a>.
--   This version does not force these values.
--   
--   <h4><b>Note on complexity</b></h4>
--   
--   This function is asymptotically optimal. Given <tt>n :: Map a b, m ::
--   Map b c</tt>, the composition essentially maps each <tt>a</tt> in
--   <tt>n</tt> to <tt>Maybe c</tt>, since the composed lookup yields
--   either one of the <tt>c</tt> in <tt>m</tt> or <tt>Nothing</tt>. The
--   number of possible such mappings is &lt;math&gt;. We now follow a
--   similar reasoning to the one for <a>sorting</a>. To distinguish
--   between &lt;math&gt; possible values, we need &lt;math&gt; bits. Thus,
--   we have a lower bound of &lt;math&gt; bits. <tt>Map</tt> lookups are
--   comparison-based, and each comparison gives us at most one bit of
--   information: in the worst case we'll always be left with at least half
--   of the remaining possible values, meaning we need at least as many
--   comparisons as we need bits.
compose :: Ord b => Map b c -> Map a b -> Map a c

-- | &lt;math&gt;. An unsafe general combining function.
--   
--   <b>Warning</b>: This function can produce corrupt maps and its results
--   may depend on the internal structures of its inputs. Users should
--   prefer <a>merge</a> or <a>mergeA</a>.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>Map</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt>,
--   <tt><a>filterWithKey</a> f</tt>, or <tt><a>mapMaybeWithKey</a> f</tt>
--   could be used for any <tt>f</tt>.
mergeWithKey :: Ord k => (k -> a -> b -> Maybe c) -> (Map k a -> Map k c) -> (Map k b -> Map k c) -> Map k a -> Map k b -> Map k c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f m == <a>fromList</a>
--   &lt;$&gt; <a>traverse</a> (\(k, v) -&gt; (,) k &lt;$&gt; f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)

-- | &lt;math&gt;. The function <a>mapAccum</a> threads an accumulating
--   argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumWithKey</a> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. The function <a>mapAccumRWithKey</a> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> k -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   If <tt>f</tt> is monotonically non-decreasing, this function takes
--   &lt;math&gt; time.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>. The value at the greater of the two
--   original keys is used as the first argument to <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   valid (mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")])) == True
--   valid (mapKeysMonotonic (\ _ -&gt; 1)     (fromList [(5,"a"), (3,"b")])) == False
--   </pre>
mapKeysMonotonic :: (k1 -> k2) -> Map k1 a -> Map k2 a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (k -> a -> m) -> Map k a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (k -> a -> b -> b) -> b -> Map k a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: Map k a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: Map k a -> [k]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Return all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: Map k a -> [(k, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [3,5]
--   keysSet empty == Data.Set.empty
--   </pre>
keysSet :: Map k a -> Set k

-- | &lt;math&gt;. The set of all elements of the map contained in
--   <a>Arg</a>s.
--   
--   <pre>
--   argSet (fromList [(5,"a"), (3,"b")]) == Data.Set.fromList [Arg 3 "b",Arg 5 "a"]
--   argSet empty == Data.Set.empty
--   </pre>
argSet :: Map k a -> Set (Arg k a)

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: Map k a -> [(k, a)]

-- | &lt;math&gt;. Filter all values that satisfy the predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys that satisfy the predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Filter all keys/values that satisfy the predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (k -> a -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Restrict a <a>Map</a> to only those keys found in a
--   <a>Set</a>.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   m `restrictKeys` s = m <a>`intersection`</a> <a>fromSet</a> (const ()) s
--   </pre>
restrictKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Remove all keys in a <a>Set</a> from a <a>Map</a>.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   m `withoutKeys` s = m <a>`difference`</a> <a>fromSet</a> (const ()) s
--   </pre>
withoutKeys :: Ord k => Map k a -> Set k -> Map k a

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Partition the map according to a predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all keys <tt>j</tt> and <tt>k</tt>
--   in the map, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>. See note at
--   <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all keys
--   <tt>j</tt> and <tt>k</tt> in the map, <tt>j &lt; k ==&gt; p j &gt;= p
--   k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = partitionWithKey (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point where the predicate switches from holding to not holding (where
--   the predicate is seen to hold before the first key and to fail after
--   the last key).
spanAntitone :: (k -> Bool) -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (k -> a -> Maybe b) -> Map k a -> Map k b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (k -> a -> Either b c) -> Map k a -> (Map k b, Map k c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where the keys in <tt>map1</tt> are smaller than
--   <tt>k</tt> and the keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Ord k => k -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The expression (<tt><a>splitLookup</a> k map</tt>)
--   splits a map just like <a>split</a> but also returns <tt><a>lookup</a>
--   k map</tt>.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Ord k => k -> Map k a -> (Map k a, Maybe a, Map k a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d')],fromList [(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than three
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: Map k b -> [Map k b]

-- | &lt;math&gt;. This function is defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f t1 t2</tt>)
--   returns <a>True</a> if all keys in <tt>t1</tt> are in tree
--   <tt>t2</tt>, and when <tt>f</tt> returns <a>True</a> when applied to
--   their respective values. For example, the following expressions are
--   all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;=) (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1),('b',2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [('a',2)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (&lt;)  (fromList [('a',1)]) (fromList [('a',1),('b',2)])
--   isSubmapOfBy (==) (fromList [('a',1),('b',2)]) (fromList [('a',1)])
--   </pre>
--   
--   Note that <tt>isSubmapOfBy (_ _ -&gt; True) m1 m2</tt> tests whether
--   all the keys in <tt>m1</tt> are also keys in <tt>m2</tt>.
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: (Ord k, Eq a) => Map k a -> Map k a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | &lt;math&gt;. Look up the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   
--   <pre>
--   isJust (lookupIndex 2 (fromList [(5,"a"), (3,"b")]))   == False
--   fromJust (lookupIndex 3 (fromList [(5,"a"), (3,"b")])) == 0
--   fromJust (lookupIndex 5 (fromList [(5,"a"), (3,"b")])) == 1
--   isJust (lookupIndex 6 (fromList [(5,"a"), (3,"b")]))   == False
--   </pre>
lookupIndex :: Ord k => k -> Map k a -> Maybe Int

-- | &lt;math&gt;. Return the <i>index</i> of a key, which is its
--   zero-based index in the sequence sorted by keys. The index is a number
--   from <i>0</i> up to, but not including, the <a>size</a> of the map.
--   Calls <a>error</a> when the key is not a <a>member</a> of the map.
--   
--   <pre>
--   findIndex 2 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   findIndex 3 (fromList [(5,"a"), (3,"b")]) == 0
--   findIndex 5 (fromList [(5,"a"), (3,"b")]) == 1
--   findIndex 6 (fromList [(5,"a"), (3,"b")])    Error: element is not in the map
--   </pre>
findIndex :: Ord k => k -> Map k a -> Int

-- | &lt;math&gt;. Retrieve an element by its <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   elemAt 0 (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a")
--   elemAt 2 (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
elemAt :: Int -> Map k a -> (k, a)

-- | &lt;math&gt;. Update the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   updateAt (\ _ _ -&gt; Just "x") 0    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "x"), (5, "a")]
--   updateAt (\ _ _ -&gt; Just "x") 1    (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "x")]
--   updateAt (\ _ _ -&gt; Just "x") 2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\ _ _ -&gt; Just "x") (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  0    (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   updateAt (\_ _  -&gt; Nothing)  1    (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   updateAt (\_ _  -&gt; Nothing)  2    (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   updateAt (\_ _  -&gt; Nothing)  (-1) (fromList [(5,"a"), (3,"b")])    Error: index out of range
--   </pre>
updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a

-- | &lt;math&gt;. Delete the element at <i>index</i>, i.e. by its
--   zero-based index in the sequence sorted by keys. If the <i>index</i>
--   is out of range (less than zero, greater or equal to <a>size</a> of
--   the map), <a>error</a> is called.
--   
--   <pre>
--   deleteAt 0  (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   deleteAt 1  (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   deleteAt 2 (fromList [(5,"a"), (3,"b")])     Error: index out of range
--   deleteAt (-1) (fromList [(5,"a"), (3,"b")])  Error: index out of range
--   </pre>
deleteAt :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Take a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   take n = <a>fromDistinctAscList</a> . <a>take</a> n . <a>toAscList</a>
--   </pre>
take :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Drop a given number of entries in key order, beginning
--   with the smallest keys.
--   
--   <pre>
--   drop n = <a>fromDistinctAscList</a> . <a>drop</a> n . <a>toAscList</a>
--   </pre>
drop :: Int -> Map k a -> Map k a

-- | &lt;math&gt;. Split a map at a particular index.
--   
--   <pre>
--   splitAt !n !xs = (<a>take</a> n xs, <a>drop</a> n xs)
--   </pre>
splitAt :: Int -> Map k a -> (Map k a, Map k a)

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMin (fromList [(5,"a"), (3,"b")]) == Just (3,"b")
--   lookupMin empty = Nothing
--   </pre>
lookupMin :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
--   
--   <pre>
--   lookupMax (fromList [(5,"a"), (3,"b")]) == Just (5,"a")
--   lookupMax empty = Nothing
--   </pre>
lookupMax :: Map k a -> Maybe (k, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMin (fromList [(5,"a"), (3,"b")]) == (3,"b")
--   findMin empty                            Error: empty map has no minimal element
--   </pre>
findMin :: Map k a -> (k, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
--   
--   <pre>
--   findMax (fromList [(5,"a"), (3,"b")]) == (5,"a")
--   findMax empty                            Error: empty map has no maximal element
--   </pre>
findMax :: Map k a -> (k, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMin (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(5,"a"), (7,"c")]
--   deleteMin empty == empty
--   </pre>
deleteMin :: Map k a -> Map k a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   <pre>
--   deleteMax (fromList [(5,"a"), (3,"b"), (7,"c")]) == fromList [(3,"b"), (5,"a")]
--   deleteMax empty == empty
--   </pre>
deleteMax :: Map k a -> Map k a

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
--   deleteFindMin empty                                      Error: can not return the minimal element of an empty map
--   </pre>
deleteFindMin :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
--   deleteFindMax empty                                      Error: can not return the maximal element of an empty map
--   </pre>
deleteFindMax :: Map k a -> ((k, a), Map k a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (k -> a -> Maybe a) -> Map k a -> Map k a

-- | &lt;math&gt;. Retrieves the value associated with minimal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   minView (fromList [(5,"a"), (3,"b")]) == Just ("b", singleton 5 "a")
--   minView empty == Nothing
--   </pre>
minView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the value associated with maximal key of the
--   map, and the map stripped of that element, or <a>Nothing</a> if passed
--   an empty map.
--   
--   <pre>
--   maxView (fromList [(5,"a"), (3,"b")]) == Just ("a", singleton 3 "b")
--   maxView empty == Nothing
--   </pre>
maxView :: Map k a -> Maybe (a, Map k a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: Map k a -> Maybe ((k, a), Map k a)

-- | &lt;math&gt;. Test if the internal map structure is valid.
--   
--   <pre>
--   valid (fromAscList [(3,"b"), (5,"a")]) == True
--   valid (fromAscList [(5,"a"), (3,"b")]) == False
--   </pre>
valid :: Ord k => Map k a -> Bool


-- | <h1>Finite Maps (lazy interface)</h1>
--   
--   This module re-exports the value lazy <a>Data.Map.Lazy</a> API.
--   
--   The <tt><a>Map</a> k v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>k</tt> to values of type
--   <tt>v</tt>. A <a>Map</a> is strict in its keys but lazy in its values.
--   
--   The functions in <a>Data.Map.Strict</a> are careful to force values
--   before installing them in a <a>Map</a>. This is usually more efficient
--   in cases where laziness is not essential. The functions in this module
--   do not do so.
--   
--   When deciding if this is the correct data structure to use, consider:
--   
--   <ul>
--   <li>If you are using <a>Int</a> keys, you will get much better
--   performance for most operations using <a>Data.IntMap.Lazy</a>.</li>
--   <li>If you don't care about ordering, consider using
--   <tt>Data.HashMap.Lazy</tt> from the <a>unordered-containers</a>
--   package instead.</li>
--   </ul>
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.Map (Map)
--   import qualified Data.Map as Map
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Warning</h2>
--   
--   The size of a <a>Map</a> must not exceed <tt><a>maxBound</a> ::
--   <a>Int</a></tt>. Violation of this condition is not detected and if
--   the size limit is exceeded, its behaviour is undefined.
--   
--   <h2>Implementation</h2>
--   
--   The implementation of <a>Map</a> is based on <i>size balanced</i>
--   binary trees (or trees of <i>bounded balance</i>) as described by:
--   
--   <ul>
--   <li>Stephen Adams, "<i>Efficient sets—a balancing act</i>", Journal of
--   Functional Programming 3(4):553-562, October 1993,
--   <a>https://doi.org/10.1017/S0956796800000885</a>,
--   <a>https://groups.csail.mit.edu/mac/users/adams/BB/index.html</a>.</li>
--   <li>J. Nievergelt and E.M. Reingold, "<i>Binary search trees of
--   bounded balance</i>", SIAM journal of computing 2(1), March 1973.
--   <a>https://doi.org/10.1137/0202005</a>.</li>
--   <li>Yoichi Hirai and Kazuhiko Yamamoto, "<i>Balancing weight-balanced
--   trees</i>", Journal of Functional Programming 21(3):287-307, 2011,
--   <a>https://doi.org/10.1017/S0956796811000104</a></li>
--   </ul>
--   
--   Bounds for <a>union</a>, <a>intersection</a>, and <a>difference</a>
--   are as given by
--   
--   <ul>
--   <li>Guy Blelloch, Daniel Ferizovic, and Yihan Sun, "<i>Parallel
--   Ordered Sets Using Join</i>",
--   <a>https://arxiv.org/abs/1602.02120v4</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   The time complexity is given for each operation in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map.
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> take
--   &lt;math&gt; time.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
module Data.Map


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Int Sets (internals)</h1>
--   
--   The <tt><a>IntSet</a></tt> type represents a set of elements of type
--   <tt>Int</tt>. An <tt>IntSet</tt> is strict in its elements.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced set implementation (see
--   <a>Data.Set</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
--   
--   Additionally, this implementation places bitmaps in the leaves of the
--   tree. Their size is the natural size of a machine word (32 or 64 bits)
--   and greatly reduces the memory footprint and execution times for dense
--   sets, e.g. sets where it is likely that many values lie close to each
--   other. The asymptotics are not affected by this optimization.
module Data.IntSet.Internal

-- | A set of integers.
data IntSet
Bin :: Prefix -> IntSet -> IntSet -> IntSet
Tip :: Int -> BitMap -> IntSet
Nil :: IntSet
type Key = Int
type BitMap = Word

-- | &lt;math&gt;. See <a>difference</a>.
(\\) :: IntSet -> IntSet -> IntSet
infixl 9 \\

-- | &lt;math&gt;. Is the set empty?
null :: IntSet -> Bool

-- | &lt;math&gt;. Cardinality of the set.
size :: IntSet -> Int

-- | &lt;math&gt;. Is the value a member of the set?
member :: Key -> IntSet -> Bool

-- | &lt;math&gt;. Is the element not in the set?
notMember :: Key -> IntSet -> Bool

-- | &lt;math&gt;. Find largest element smaller than the given one.
--   
--   <pre>
--   lookupLT 3 (fromList [3, 5]) == Nothing
--   lookupLT 5 (fromList [3, 5]) == Just 3
--   </pre>
lookupLT :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find smallest element greater than the given one.
--   
--   <pre>
--   lookupGT 4 (fromList [3, 5]) == Just 5
--   lookupGT 5 (fromList [3, 5]) == Nothing
--   </pre>
lookupGT :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find largest element smaller or equal to the given one.
--   
--   <pre>
--   lookupLE 2 (fromList [3, 5]) == Nothing
--   lookupLE 4 (fromList [3, 5]) == Just 3
--   lookupLE 5 (fromList [3, 5]) == Just 5
--   </pre>
lookupLE :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find smallest element greater or equal to the given one.
--   
--   <pre>
--   lookupGE 3 (fromList [3, 5]) == Just 3
--   lookupGE 4 (fromList [3, 5]) == Just 5
--   lookupGE 6 (fromList [3, 5]) == Nothing
--   </pre>
lookupGE :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Is this a subset? <tt>(s1 `isSubsetOf` s2)</tt> tells
--   whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. Check whether two sets are disjoint (i.e. their
--   intersection is empty).
--   
--   <pre>
--   disjoint (fromList [2,4,6])   (fromList [1,3])     == True
--   disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
--   disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
--   disjoint (fromList [])        (fromList [])        == True
--   </pre>
disjoint :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. The empty set.
empty :: IntSet

-- | &lt;math&gt;. A set of one element.
singleton :: Key -> IntSet

-- | &lt;math&gt;. Create a set from a range of integers.
--   
--   <pre>
--   fromRange (low, high) == fromList [low..high]
--   </pre>
fromRange :: (Key, Key) -> IntSet

-- | &lt;math&gt;. Add a value to the set. There is no left- or right bias
--   for IntSets.
insert :: Key -> IntSet -> IntSet

-- | &lt;math&gt;. Delete a value in the set. Returns the original set when
--   the value was not present.
delete :: Key -> IntSet -> IntSet

-- | &lt;math&gt;. <tt>(<a>alterF</a> f x s)</tt> can delete or insert
--   <tt>x</tt> in <tt>s</tt> depending on whether it is already present in
--   <tt>s</tt>.
--   
--   In short:
--   
--   <pre>
--   <a>member</a> x &lt;$&gt; <a>alterF</a> f x s = f (<a>member</a> x s)
--   </pre>
--   
--   Note: <a>alterF</a> is a variant of the <tt>at</tt> combinator from
--   <a>Control.Lens.At</a>.
alterF :: Functor f => (Bool -> f Bool) -> Key -> IntSet -> f IntSet

-- | &lt;math&gt;. The union of two sets.
union :: IntSet -> IntSet -> IntSet

-- | The union of a list of sets.
unions :: Foldable f => f IntSet -> IntSet

-- | &lt;math&gt;. Difference between two sets.
difference :: IntSet -> IntSet -> IntSet

-- | &lt;math&gt;. The intersection of two sets.
intersection :: IntSet -> IntSet -> IntSet

-- | The intersection of a series of sets. Intersections are performed
--   left-to-right.
intersections :: NonEmpty IntSet -> IntSet

-- | &lt;math&gt;. The symmetric difference of two sets.
--   
--   The result contains elements that appear in exactly one of the two
--   sets.
--   
--   <pre>
--   symmetricDifference (fromList [0,2,4,6]) (fromList [0,3,6,9]) == fromList [2,3,4,9]
--   </pre>
symmetricDifference :: IntSet -> IntSet -> IntSet

-- | <tt>IntSet</tt>s form a <a>Semigroup</a> under <a>intersection</a>.
--   
--   A <tt>Monoid</tt> instance is not defined because it would be
--   impractical to construct <tt>mempty</tt>, the <tt>IntSet</tt>
--   containing all <tt>Int</tt>s.
newtype Intersection
Intersection :: IntSet -> Intersection
[getIntersection] :: Intersection -> IntSet

-- | &lt;math&gt;. Filter all elements that satisfy some predicate.
filter :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. partition the set according to some predicate.
partition :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. Take while a predicate on the elements holds. The user
--   is responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
--   takeWhileAntitone p = <a>filter</a> p
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. Drop while a predicate on the elements holds. The user
--   is responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
--   dropWhileAntitone p = <a>filter</a> (not . p)
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. Divide a set at the point where a predicate on the
--   elements stops holding. The user is responsible for ensuring that for
--   all <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partition</a> p xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. The expression (<tt><a>split</a> x set</tt>) is a pair
--   <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements of
--   <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
--   elements of <tt>set</tt> greater than <tt>x</tt>.
--   
--   <pre>
--   split 3 (fromList [1..5]) == (fromList [1,2], fromList [4,5])
--   </pre>
split :: Key -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot element was found in the original set.
splitMember :: Key -> IntSet -> (IntSet, Bool, IntSet)

-- | &lt;math&gt;. Decompose a set into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a set in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList [1..120]) == [fromList [1..63],fromList [64..120]]
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   subsets, but you should not depend on this behaviour because it can
--   change in the future without notice. Also, the current version does
--   not continue splitting all the way to individual singleton sets -- it
--   stops at some point.
splitRoot :: IntSet -> [IntSet]

-- | &lt;math&gt;. <tt><a>map</a> f s</tt> is the set obtained by applying
--   <tt>f</tt> to each element of <tt>s</tt>.
--   
--   It's worth noting that the size of the result may be smaller if, for
--   some <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: (Key -> Key) -> IntSet -> IntSet

-- | &lt;math&gt;. The
--   
--   <tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but works only
--   when <tt>f</tt> is strictly increasing. Semi-formally, we have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapMonotonic f s == map f s
--       where ls = toList s
--   </pre>
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>map</a> if the precondition may not hold.
mapMonotonic :: (Key -> Key) -> IntSet -> IntSet

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toAscList set = foldr (:) [] set
--   </pre>
foldr :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toDescList set = foldl (flip (:)) [] set
--   </pre>
foldl :: (a -> Key -> a) -> a -> IntSet -> a

-- | &lt;math&gt;. Map the elements in the set to a monoid and combine with
--   <tt>(&lt;&gt;)</tt>.
foldMap :: Monoid a => (Key -> a) -> IntSet -> a

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> Key -> a) -> a -> IntSet -> a

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator.

-- | <i>Deprecated: Use Data.IntSet.foldr instead</i>
fold :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. The minimal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMin :: IntSet -> Maybe Key

-- | &lt;math&gt;. The maximal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMax :: IntSet -> Maybe Key

-- | &lt;math&gt;. The minimal element of the set. Calls <a>error</a> if
--   the set is empty.
findMin :: IntSet -> Key

-- | &lt;math&gt;. The maximal element of the set. Calls <a>error</a> if
--   the set is empty.
findMax :: IntSet -> Key

-- | &lt;math&gt;. Delete the minimal element. Returns an empty set if the
--   set is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
--   was already empty.
deleteMin :: IntSet -> IntSet

-- | &lt;math&gt;. Delete the maximal element. Returns an empty set if the
--   set is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
--   was already empty.
deleteMax :: IntSet -> IntSet

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: IntSet -> (Key, IntSet)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: IntSet -> (Key, IntSet)

-- | &lt;math&gt;. Retrieves the maximal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: IntSet -> Maybe (Key, IntSet)

-- | &lt;math&gt;. Retrieves the minimal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: IntSet -> Maybe (Key, IntSet)

-- | &lt;math&gt;. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: IntSet -> [Key]

-- | &lt;math&gt;. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: IntSet -> [Key]

-- | &lt;math&gt;. Create a set from a list of integers.
fromList :: [Key] -> IntSet

-- | &lt;math&gt;. Convert the set to an ascending list of elements.
--   Subject to list fusion.
toAscList :: IntSet -> [Key]

-- | &lt;math&gt;. Convert the set to a descending list of elements.
--   Subject to list fusion.
toDescList :: IntSet -> [Key]

-- | &lt;math&gt;. Build a set from an ascending list of elements.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromAscList :: [Key] -> IntSet

-- | &lt;math&gt;. Build a set from an ascending list of distinct elements.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctAscList :: [Key] -> IntSet

-- | &lt;math&gt;. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: IntSet -> String

-- | &lt;math&gt;. The expression (<tt><a>showTreeWith</a> hang wide
--   map</tt>) shows the tree that implements the set. If <tt>hang</tt> is
--   <a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
showTreeWith :: Bool -> Bool -> IntSet -> String
suffixBitMask :: Int
prefixBitMask :: Int
bitmapOf :: Int -> BitMap
instance GHC.Internal.Data.Data.Data Data.IntSet.Internal.IntSet
instance GHC.Internal.Classes.Eq Data.IntSet.Internal.IntSet
instance GHC.Internal.Classes.Eq Data.IntSet.Internal.Intersection
instance GHC.Internal.IsList.IsList Data.IntSet.Internal.IntSet
instance GHC.Internal.TH.Lift.Lift Data.IntSet.Internal.IntSet
instance GHC.Internal.Base.Monoid Data.IntSet.Internal.IntSet
instance Control.DeepSeq.NFData Data.IntSet.Internal.IntSet
instance GHC.Internal.Classes.Ord Data.IntSet.Internal.IntSet
instance GHC.Internal.Classes.Ord Data.IntSet.Internal.Intersection
instance GHC.Internal.Read.Read Data.IntSet.Internal.IntSet
instance GHC.Internal.Base.Semigroup Data.IntSet.Internal.IntSet
instance GHC.Internal.Base.Semigroup Data.IntSet.Internal.Intersection
instance GHC.Internal.Show.Show Data.IntSet.Internal.IntSet
instance GHC.Internal.Show.Show Data.IntSet.Internal.Intersection


-- | <h1>Finite Int Sets</h1>
--   
--   The <tt><a>IntSet</a></tt> type represents a set of elements of type
--   <tt>Int</tt>. An <tt>IntSet</tt> is strict in its elements.
--   
--   For a walkthrough of the most commonly used functions see their
--   <a>sets introduction</a>.
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntSet (IntSet)
--   import qualified Data.IntSet as IntSet
--   </pre>
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced set implementation (see
--   <a>Data.Set</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
--   
--   Additionally, this implementation places bitmaps in the leaves of the
--   tree. Their size is the natural size of a machine word (32 or 64 bits)
--   and greatly reduces the memory footprint and execution times for dense
--   sets, e.g. sets where it is likely that many values lie close to each
--   other. The asymptotics are not affected by this optimization.
--   
--   <h2>Performance information</h2>
--   
--   The time complexity is given for each operation in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map and &lt;math&gt; referring to the number of bits in an
--   <a>Int</a> (32 or 64).
--   
--   Operations like <a>member</a>, <a>insert</a>, and <a>delete</a> have a
--   worst-case complexity of &lt;math&gt;. This means that the operation
--   can become linear in the number of elements with a maximum of
--   &lt;math&gt; -- the number of bits in an <a>Int</a> (32 or 64). These
--   peculiar asymptotics are determined by the depth of the Patricia
--   trees:
--   
--   <ul>
--   <li>even for an extremely unbalanced tree, the depth cannot be larger
--   than the number of elements &lt;math&gt;,</li>
--   <li>each level of a Patricia tree determines at least one more bit
--   shared by all subelements, so there could not be more than
--   &lt;math&gt; levels.</li>
--   </ul>
--   
--   If all &lt;math&gt; elements in the tree are between 0 and
--   &lt;math&gt; (or, say, between &lt;math&gt; and &lt;math&gt;), the
--   estimate can be refined to &lt;math&gt;. If the set is sufficiently
--   "dense", this becomes &lt;math&gt; or simply the familiar
--   &lt;math&gt;, matching balanced binary trees.
--   
--   The most performant scenario for <a>IntSet</a> are elements from a
--   contiguous subset, in which case the complexity is proportional to
--   &lt;math&gt;, capped by &lt;math&gt;. The worst scenario are
--   exponentially growing elements (1,2,4, ldots,2^n), for which
--   complexity grows as fast as &lt;math&gt; but again is capped by
--   &lt;math&gt;.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input sets respectively.
module Data.IntSet

-- | A set of integers.
data IntSet
type Key = Int

-- | &lt;math&gt;. The empty set.
empty :: IntSet

-- | &lt;math&gt;. A set of one element.
singleton :: Key -> IntSet

-- | &lt;math&gt;. Create a set from a list of integers.
fromList :: [Key] -> IntSet

-- | &lt;math&gt;. Create a set from a range of integers.
--   
--   <pre>
--   fromRange (low, high) == fromList [low..high]
--   </pre>
fromRange :: (Key, Key) -> IntSet

-- | &lt;math&gt;. Build a set from an ascending list of elements.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromAscList :: [Key] -> IntSet

-- | &lt;math&gt;. Build a set from an ascending list of distinct elements.
--   
--   <b>Warning</b>: This function should be used only if the elements are
--   in strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
fromDistinctAscList :: [Key] -> IntSet

-- | &lt;math&gt;. Add a value to the set. There is no left- or right bias
--   for IntSets.
insert :: Key -> IntSet -> IntSet

-- | &lt;math&gt;. Delete a value in the set. Returns the original set when
--   the value was not present.
delete :: Key -> IntSet -> IntSet

-- | &lt;math&gt;. <tt>(<a>alterF</a> f x s)</tt> can delete or insert
--   <tt>x</tt> in <tt>s</tt> depending on whether it is already present in
--   <tt>s</tt>.
--   
--   In short:
--   
--   <pre>
--   <a>member</a> x &lt;$&gt; <a>alterF</a> f x s = f (<a>member</a> x s)
--   </pre>
--   
--   Note: <a>alterF</a> is a variant of the <tt>at</tt> combinator from
--   <a>Control.Lens.At</a>.
alterF :: Functor f => (Bool -> f Bool) -> Key -> IntSet -> f IntSet

-- | &lt;math&gt;. Is the value a member of the set?
member :: Key -> IntSet -> Bool

-- | &lt;math&gt;. Is the element not in the set?
notMember :: Key -> IntSet -> Bool

-- | &lt;math&gt;. Find largest element smaller than the given one.
--   
--   <pre>
--   lookupLT 3 (fromList [3, 5]) == Nothing
--   lookupLT 5 (fromList [3, 5]) == Just 3
--   </pre>
lookupLT :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find smallest element greater than the given one.
--   
--   <pre>
--   lookupGT 4 (fromList [3, 5]) == Just 5
--   lookupGT 5 (fromList [3, 5]) == Nothing
--   </pre>
lookupGT :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find largest element smaller or equal to the given one.
--   
--   <pre>
--   lookupLE 2 (fromList [3, 5]) == Nothing
--   lookupLE 4 (fromList [3, 5]) == Just 3
--   lookupLE 5 (fromList [3, 5]) == Just 5
--   </pre>
lookupLE :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Find smallest element greater or equal to the given one.
--   
--   <pre>
--   lookupGE 3 (fromList [3, 5]) == Just 3
--   lookupGE 4 (fromList [3, 5]) == Just 5
--   lookupGE 6 (fromList [3, 5]) == Nothing
--   </pre>
lookupGE :: Key -> IntSet -> Maybe Key

-- | &lt;math&gt;. Is the set empty?
null :: IntSet -> Bool

-- | &lt;math&gt;. Cardinality of the set.
size :: IntSet -> Int

-- | &lt;math&gt;. Is this a subset? <tt>(s1 `isSubsetOf` s2)</tt> tells
--   whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. Check whether two sets are disjoint (i.e. their
--   intersection is empty).
--   
--   <pre>
--   disjoint (fromList [2,4,6])   (fromList [1,3])     == True
--   disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7]) == False
--   disjoint (fromList [1,2])     (fromList [1,2,3,4]) == False
--   disjoint (fromList [])        (fromList [])        == True
--   </pre>
disjoint :: IntSet -> IntSet -> Bool

-- | &lt;math&gt;. The union of two sets.
union :: IntSet -> IntSet -> IntSet

-- | The union of a list of sets.
unions :: Foldable f => f IntSet -> IntSet

-- | &lt;math&gt;. Difference between two sets.
difference :: IntSet -> IntSet -> IntSet

-- | &lt;math&gt;. See <a>difference</a>.
(\\) :: IntSet -> IntSet -> IntSet
infixl 9 \\

-- | &lt;math&gt;. The intersection of two sets.
intersection :: IntSet -> IntSet -> IntSet

-- | The intersection of a series of sets. Intersections are performed
--   left-to-right.
intersections :: NonEmpty IntSet -> IntSet

-- | &lt;math&gt;. The symmetric difference of two sets.
--   
--   The result contains elements that appear in exactly one of the two
--   sets.
--   
--   <pre>
--   symmetricDifference (fromList [0,2,4,6]) (fromList [0,3,6,9]) == fromList [2,3,4,9]
--   </pre>
symmetricDifference :: IntSet -> IntSet -> IntSet

-- | <tt>IntSet</tt>s form a <a>Semigroup</a> under <a>intersection</a>.
--   
--   A <tt>Monoid</tt> instance is not defined because it would be
--   impractical to construct <tt>mempty</tt>, the <tt>IntSet</tt>
--   containing all <tt>Int</tt>s.
newtype Intersection
Intersection :: IntSet -> Intersection
[getIntersection] :: Intersection -> IntSet

-- | &lt;math&gt;. Filter all elements that satisfy some predicate.
filter :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. partition the set according to some predicate.
partition :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. Take while a predicate on the elements holds. The user
--   is responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> p . <a>toList</a>
--   takeWhileAntitone p = <a>filter</a> p
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. Drop while a predicate on the elements holds. The user
--   is responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> p . <a>toList</a>
--   dropWhileAntitone p = <a>filter</a> (not . p)
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntSet -> IntSet

-- | &lt;math&gt;. Divide a set at the point where a predicate on the
--   elements stops holding. The user is responsible for ensuring that for
--   all <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partition</a> p xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the set at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. The expression (<tt><a>split</a> x set</tt>) is a pair
--   <tt>(set1,set2)</tt> where <tt>set1</tt> comprises the elements of
--   <tt>set</tt> less than <tt>x</tt> and <tt>set2</tt> comprises the
--   elements of <tt>set</tt> greater than <tt>x</tt>.
--   
--   <pre>
--   split 3 (fromList [1..5]) == (fromList [1,2], fromList [4,5])
--   </pre>
split :: Key -> IntSet -> (IntSet, IntSet)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot element was found in the original set.
splitMember :: Key -> IntSet -> (IntSet, Bool, IntSet)

-- | &lt;math&gt;. Decompose a set into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a set in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList [1..120]) == [fromList [1..63],fromList [64..120]]
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   subsets, but you should not depend on this behaviour because it can
--   change in the future without notice. Also, the current version does
--   not continue splitting all the way to individual singleton sets -- it
--   stops at some point.
splitRoot :: IntSet -> [IntSet]

-- | &lt;math&gt;. <tt><a>map</a> f s</tt> is the set obtained by applying
--   <tt>f</tt> to each element of <tt>s</tt>.
--   
--   It's worth noting that the size of the result may be smaller if, for
--   some <tt>(x,y)</tt>, <tt>x /= y &amp;&amp; f x == f y</tt>
map :: (Key -> Key) -> IntSet -> IntSet

-- | &lt;math&gt;. The
--   
--   <tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but works only
--   when <tt>f</tt> is strictly increasing. Semi-formally, we have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapMonotonic f s == map f s
--       where ls = toList s
--   </pre>
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>map</a> if the precondition may not hold.
mapMonotonic :: (Key -> Key) -> IntSet -> IntSet

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toAscList set = foldr (:) [] set
--   </pre>
foldr :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. Fold the elements in the set using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   toDescList set = foldl (flip (:)) [] set
--   </pre>
foldl :: (a -> Key -> a) -> a -> IntSet -> a

-- | &lt;math&gt;. Map the elements in the set to a monoid and combine with
--   <tt>(&lt;&gt;)</tt>.
foldMap :: Monoid a => (Key -> a) -> IntSet -> a

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> Key -> a) -> a -> IntSet -> a

-- | &lt;math&gt;. Fold the elements in the set using the given
--   right-associative binary operator.

-- | <i>Deprecated: Use Data.IntSet.foldr instead</i>
fold :: (Key -> b -> b) -> b -> IntSet -> b

-- | &lt;math&gt;. The minimal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMin :: IntSet -> Maybe Key

-- | &lt;math&gt;. The maximal element of the set. Returns <a>Nothing</a>
--   if the set is empty.
lookupMax :: IntSet -> Maybe Key

-- | &lt;math&gt;. The minimal element of the set. Calls <a>error</a> if
--   the set is empty.
findMin :: IntSet -> Key

-- | &lt;math&gt;. The maximal element of the set. Calls <a>error</a> if
--   the set is empty.
findMax :: IntSet -> Key

-- | &lt;math&gt;. Delete the minimal element. Returns an empty set if the
--   set is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
--   was already empty.
deleteMin :: IntSet -> IntSet

-- | &lt;math&gt;. Delete the maximal element. Returns an empty set if the
--   set is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Set</a> – versions prior to 0.5 threw an error if the <a>IntSet</a>
--   was already empty.
deleteMax :: IntSet -> IntSet

-- | &lt;math&gt;. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: IntSet -> (Key, IntSet)

-- | &lt;math&gt;. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: IntSet -> (Key, IntSet)

-- | &lt;math&gt;. Retrieves the maximal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
maxView :: IntSet -> Maybe (Key, IntSet)

-- | &lt;math&gt;. Retrieves the minimal key of the set, and the set
--   stripped of that element, or <a>Nothing</a> if passed an empty set.
minView :: IntSet -> Maybe (Key, IntSet)

-- | &lt;math&gt;. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: IntSet -> [Key]

-- | &lt;math&gt;. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: IntSet -> [Key]

-- | &lt;math&gt;. Convert the set to an ascending list of elements.
--   Subject to list fusion.
toAscList :: IntSet -> [Key]

-- | &lt;math&gt;. Convert the set to a descending list of elements.
--   Subject to list fusion.
toDescList :: IntSet -> [Key]

-- | &lt;math&gt;. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: IntSet -> String

-- | &lt;math&gt;. The expression (<tt><a>showTreeWith</a> hang wide
--   map</tt>) shows the tree that implements the set. If <tt>hang</tt> is
--   <a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
showTreeWith :: Bool -> Bool -> IntSet -> String


-- | This module provides efficient containers-based functions on the list
--   type.
--   
--   In the documentation, &lt;math&gt; is the number of elements in the
--   list while &lt;math&gt; is the number of distinct elements in the
--   list. &lt;math&gt; is the number of bits in an <a>Int</a>.
module Data.Containers.ListUtils

-- | &lt;math&gt;. The <tt>nubOrd</tt> function removes duplicate elements
--   from a list. In particular, it keeps only the first occurrence of each
--   element. By using a <a>Set</a> internally it has better asymptotics
--   than the standard <a>nub</a> function.
--   
--   <h4>Strictness</h4>
--   
--   <tt>nubOrd</tt> is strict in the elements of the list.
--   
--   <h4>Efficiency note</h4>
--   
--   When applicable, it is almost always better to use <a>nubInt</a> or
--   <a>nubIntOn</a> instead of this function, although it can be a little
--   worse in certain pathological cases. For example, to nub a list of
--   characters, use
--   
--   <pre>
--   nubIntOn fromEnum xs
--   </pre>
nubOrd :: Ord a => [a] -> [a]

-- | The <tt>nubOrdOn</tt> function behaves just like <a>nubOrd</a> except
--   it performs comparisons not on the original datatype, but a
--   user-specified projection from that datatype.
--   
--   <h4>Strictness</h4>
--   
--   <tt>nubOrdOn</tt> is strict in the values of the function applied to
--   the elements of the list.
nubOrdOn :: Ord b => (a -> b) -> [a] -> [a]

-- | &lt;math&gt;. The <tt>nubInt</tt> function removes duplicate
--   <a>Int</a> values from a list. In particular, it keeps only the first
--   occurrence of each element. By using an <a>IntSet</a> internally, it
--   attains better asymptotics than the standard <a>nub</a> function.
--   
--   See also <a>nubIntOn</a>, a more widely applicable generalization.
--   
--   <h4>Strictness</h4>
--   
--   <tt>nubInt</tt> is strict in the elements of the list.
nubInt :: [Int] -> [Int]

-- | The <tt>nubIntOn</tt> function behaves just like <a>nubInt</a> except
--   it performs comparisons not on the original datatype, but a
--   user-specified projection from that datatype. For example,
--   <tt>nubIntOn <a>fromEnum</a></tt> can be used to nub characters and
--   typical fixed-with numerical types efficiently.
--   
--   <h4>Strictness</h4>
--   
--   <tt>nubIntOn</tt> is strict in the values of the function applied to
--   the elements of the list.
nubIntOn :: (a -> Int) -> [a] -> [a]


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Int Maps (lazy interface internals)</h1>
--   
--   The <tt><a>IntMap</a> v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>Int</tt> to values of type
--   <tt>v</tt>.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced map implementation (see
--   <a>Data.Map</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
module Data.IntMap.Internal

-- | A map of integers to values <tt>a</tt>.
data IntMap a
Bin :: Prefix -> IntMap a -> IntMap a -> IntMap a
Tip :: Key -> a -> IntMap a
Nil :: IntMap a
type Key = Int

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: IntMap a -> Key -> a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] !? 1 == Nothing
--   fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | &lt;math&gt;. Number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: IntMap a -> Int

-- | &lt;math&gt;. Is the key a member of the map?
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map?
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Look up the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
--   when the key is not an element of the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e. their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   disjoint a b == null (intersection a b)
--   </pre>
disjoint :: IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | &lt;math&gt;. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | &lt;math&gt;. Insert a new key/value pair in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value, i.e. <a>insert</a> is equivalent to
--   <tt><a>insertWith</a> <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function. <tt><a>insertWith</a>
--   f key value mp</tt> will insert the pair (key, value) into <tt>mp</tt>
--   if key does not exist in the map. If the key does exist, the function
--   will insert <tt>f new_value old_value</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function.
--   <tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert <tt>f key new_value
--   old_value</tt>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>insertLookupWithKey</a> f k x
--   map</tt>) is a pair where the first element is equal to
--   (<tt><a>lookup</a> k map</tt>) and the second element equal to
--   (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f k
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Look up and update. This function returns the original
--   value, if it is updated. This is different behavior than
--   <a>updateLookupWithKey</a>. Returns the original key value if the map
--   entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in an <a>IntMap</a>.
--   In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a>
--   k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in an
--   <a>IntMap</a>. In short : <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a>
--   f k m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | &lt;math&gt;. The (left-biased) union of two maps. It prefers the
--   first map when duplicate keys are encountered, i.e. (<tt><a>union</a>
--   == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: Foldable f => f (IntMap a) -> IntMap a

-- | The union of a list of maps, with a combining operation.
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: Foldable f => (a -> a -> a) -> f (IntMap a) -> IntMap a

-- | &lt;math&gt;. Difference between two maps (based on keys).
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. Difference with a combining function.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The (left-biased) intersection of two maps (based on
--   keys).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: IntMap a -> IntMap a -> IntMap a

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.IntMap.Strict</a> exposed a
--   version of <a>compose</a> that forced the values of the output
--   <a>IntMap</a>. This version does not force these values.
compose :: IntMap c -> IntMap Int -> IntMap c

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; Maybe
--   z</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
--   Maybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge diffPreserve diffDrop f
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
--   </pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched
--     :: (Key -&gt; x -&gt; y -&gt; Maybe z)
--     -&gt; SimpleWhenMatched x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched
--     :: (Key -&gt; x -&gt; y -&gt; z)
--     -&gt; SimpleWhenMatched x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (Key -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) x y. Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) x. Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) x. Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMissing f k x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
--   z)</tt>.
data WhenMissing (f :: Type -> Type) x y
WhenMissing :: (IntMap x -> f (IntMap y)) -> (Key -> x -> f (Maybe y)) -> WhenMissing (f :: Type -> Type) x y
[missingSubtree] :: WhenMissing (f :: Type -> Type) x y -> IntMap x -> f (IntMap y)
[missingKey] :: WhenMissing (f :: Type -> Type) x y -> Key -> x -> f (Maybe y)

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMatched f x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
newtype WhenMatched (f :: Type -> Type) x y z
WhenMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched (f :: Type -> Type) x y z
[matchedKey] :: WhenMatched (f :: Type -> Type) x y z -> Key -> x -> y -> f (Maybe z)

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3,'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>mergeA</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: Applicative f => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | &lt;math&gt;. A high-performance universal combining function. Using
--   <a>mergeWithKey</a>, all combining functions can be defined without
--   any loss of efficiency (with exception of <a>union</a>,
--   <a>difference</a> and <a>intersection</a>, where sharing of some nodes
--   is lost with <a>mergeWithKey</a>).
--   
--   <b>Warning</b>: Please make sure you know what is going on when using
--   <a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
--   growth or even corruption of the data structure.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define your custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>IntMap</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c
mergeWithKey' :: (Prefix -> IntMap c -> IntMap c -> IntMap c) -> (IntMap a -> IntMap b -> IntMap c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
--   <a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)

-- | &lt;math&gt;. The function <tt><a>mapAccum</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumWithKey</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumRWithKey</a></tt> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has slightly better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: IntMap a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: IntMap a -> [Key]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Returns all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
--   keysSet empty == Data.IntSet.empty
--   </pre>
keysSet :: IntMap a -> IntSet

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.IntSet.empty == empty
--   </pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Create a map from a list of key/value pairs.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also fromAscListWithKey'.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   </pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order and all distinct.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Filter all values that satisfy some predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys that satisfy some predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys/values that satisfy some predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. The restriction of a map to the keys in a set.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   </pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Remove all the keys in a given set from a map.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   </pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all
--   <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partitionWithKey</a> (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower than
--   <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot key was found in the original map.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | &lt;math&gt;. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
--   returns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
--   when <tt>f</tt> returns <a>True</a> when applied to their respective
--   values. For example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   </pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
findMin :: IntMap a -> (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
findMax :: IntMap a -> (Key, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMin :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMax :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete and find the minimal element. This function
--   throws an error if the map is empty. Use <a>minViewWithKey</a> if the
--   map may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Delete and find the maximal element. This function
--   throws an error if the map is empty. Use <a>maxViewWithKey</a> if the
--   map may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Retrieves the minimal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the maximal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | &lt;math&gt;. Show the tree that implements the map. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | &lt;math&gt;. The expression (<tt><a>showTreeWith</a> hang wide
--   map</tt>) shows the tree that implements the map. If <tt>hang</tt> is
--   <a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String

-- | Link two <tt>IntMap</tt>s. The maps must not be empty. The
--   <tt>Prefix</tt>es of the two maps must be different. <tt>k1</tt> must
--   share the prefix of <tt>t1</tt> and <tt>k2</tt> must share the prefix
--   of <tt>t2</tt>.
link :: Int -> IntMap a -> Int -> IntMap a -> IntMap a

-- | Link two <tt>IntMap</tt>s. The maps must not be empty. The
--   <tt>Prefix</tt>es of the two maps must be different. <tt>k1</tt> must
--   share the prefix of <tt>t1</tt>. <tt>p2</tt> must be the prefix of
--   <tt>t2</tt>.
linkKey :: Key -> IntMap a -> Prefix -> IntMap a -> IntMap a
linkWithMask :: Int -> Key -> IntMap a -> Key -> IntMap a -> IntMap a
bin :: Prefix -> IntMap a -> IntMap a -> IntMap a
binCheckLeft :: Prefix -> IntMap a -> IntMap a -> IntMap a
binCheckRight :: Prefix -> IntMap a -> IntMap a -> IntMap a

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b x. (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f _ x</tt>.
lmapWhenMissing :: forall b a (f :: Type -> Type) x. (b -> a) -> WhenMissing f a x -> WhenMissing f b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f _ y z</tt>.
contramapFirstWhenMatched :: forall b a (f :: Type -> Type) y z. (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f x _ z</tt>.
contramapSecondWhenMatched :: forall b a (f :: Type -> Type) x z. (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>, using only a
--   'Functor f' constraint.
mapGentlyWhenMissing :: forall (f :: Type -> Type) a b x. Functor f => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x</tt>, using only a
--   'Functor f' constraint.
mapGentlyWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Base.Applicative (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Applicative (Data.IntMap.Internal.WhenMissing f x)
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Control.Category.Category (Data.IntMap.Internal.WhenMatched f x)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Control.Category.Category (Data.IntMap.Internal.WhenMissing f)
instance GHC.Internal.Data.Data.Data a => GHC.Internal.Data.Data.Data (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Eq1 Data.IntMap.Internal.IntMap
instance GHC.Internal.Classes.Eq a => GHC.Internal.Classes.Eq (Data.IntMap.Internal.IntMap a)
instance GHC.Internal.Data.Foldable.Foldable Data.IntMap.Internal.IntMap
instance GHC.Internal.Base.Functor Data.IntMap.Internal.IntMap
instance GHC.Internal.Base.Functor f => GHC.Internal.Base.Functor (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Functor (Data.IntMap.Internal.WhenMissing f x)
instance GHC.Internal.IsList.IsList (Data.IntMap.Internal.IntMap a)
instance GHC.Internal.TH.Lift.Lift a => GHC.Internal.TH.Lift.Lift (Data.IntMap.Internal.IntMap a)
instance (GHC.Internal.Base.Monad f, GHC.Internal.Base.Applicative f) => GHC.Internal.Base.Monad (Data.IntMap.Internal.WhenMatched f x y)
instance (GHC.Internal.Base.Applicative f, GHC.Internal.Base.Monad f) => GHC.Internal.Base.Monad (Data.IntMap.Internal.WhenMissing f x)
instance GHC.Internal.Base.Monoid (Data.IntMap.Internal.IntMap a)
instance Control.DeepSeq.NFData1 Data.IntMap.Internal.IntMap
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Ord1 Data.IntMap.Internal.IntMap
instance GHC.Internal.Classes.Ord a => GHC.Internal.Classes.Ord (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Read1 Data.IntMap.Internal.IntMap
instance GHC.Internal.Read.Read e => GHC.Internal.Read.Read (Data.IntMap.Internal.IntMap e)
instance GHC.Internal.Base.Semigroup (Data.IntMap.Internal.IntMap a)
instance Data.Functor.Classes.Show1 Data.IntMap.Internal.IntMap
instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Data.IntMap.Internal.IntMap a)
instance GHC.Internal.Data.Traversable.Traversable Data.IntMap.Internal.IntMap


-- | <h1>WARNING</h1>
--   
--   This module is considered <b>internal</b>.
--   
--   The Package Versioning Policy <b>does not apply</b>.
--   
--   The contents of this module may change <b>in any way whatsoever</b>
--   and <b>without any warning</b> between minor versions of this package.
--   
--   Authors importing this module are expected to track development
--   closely.
--   
--   <h1>Finite Int Maps (strict interface internals)</h1>
--   
--   The <tt><a>IntMap</a> v</tt> type represents a finite map (sometimes
--   called a dictionary) from key of type <tt>Int</tt> to values of type
--   <tt>v</tt>.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced map implementation (see
--   <a>Data.Map</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
module Data.IntMap.Strict.Internal

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | &lt;math&gt;. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.IntSet.empty == empty
--   </pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | &lt;math&gt;. Create a map from a list of key/value pairs.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also fromAscListWithKey'.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   </pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order and all distinct.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Insert a new key/value pair in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value, i.e. <a>insert</a> is equivalent to
--   <tt><a>insertWith</a> <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function. <tt><a>insertWith</a>
--   f key value mp</tt> will insert the pair (key, value) into <tt>mp</tt>
--   if key does not exist in the map. If the key does exist, the function
--   will insert <tt>f new_value old_value</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function.
--   <tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert <tt>f key new_value
--   old_value</tt>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   If the key exists in the map, this function is lazy in <tt>value</tt>
--   but strict in the result of <tt>f</tt>.
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>insertLookupWithKey</a> f k x
--   map</tt>) is a pair where the first element is equal to
--   (<tt><a>lookup</a> k map</tt>) and the second element equal to
--   (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f k
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Look up and update. The function returns original value,
--   if it is updated. This is different behavior than
--   <a>updateLookupWithKey</a>. Returns the original key value if the map
--   entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in an <a>IntMap</a>.
--   In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a>
--   k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in an
--   <a>IntMap</a>. In short : <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a>
--   f k m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | &lt;math&gt;. Look up the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] !? 1 == Nothing
--   fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: IntMap a -> Key -> a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
--   when the key is not an element of the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | &lt;math&gt;. Is the key a member of the map?
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map?
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | &lt;math&gt;. Number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: IntMap a -> Int

-- | &lt;math&gt;. The (left-biased) union of two maps. It prefers the
--   first map when duplicate keys are encountered, i.e. (<tt><a>union</a>
--   == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: Foldable f => f (IntMap a) -> IntMap a

-- | The union of a list of maps, with a combining operation.
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: Foldable f => (a -> a -> a) -> f (IntMap a) -> IntMap a

-- | &lt;math&gt;. Difference between two maps (based on keys).
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | &lt;math&gt;. Difference with a combining function.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The (left-biased) intersection of two maps (based on
--   keys).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e. their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   disjoint a b == null (intersection a b)
--   </pre>
disjoint :: IntMap a -> IntMap b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.IntMap.Strict</a> exposed a
--   version of <a>compose</a> that forced the values of the output
--   <a>IntMap</a>. This version does not force these values.
compose :: IntMap c -> IntMap Int -> IntMap c

-- | &lt;math&gt;. A high-performance universal combining function. Using
--   <a>mergeWithKey</a>, all combining functions can be defined without
--   any loss of efficiency (with exception of <a>union</a>,
--   <a>difference</a> and <a>intersection</a>, where sharing of some nodes
--   is lost with <a>mergeWithKey</a>).
--   
--   <b>Warning</b>: Please make sure you know what is going on when using
--   <a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
--   growth or even corruption of the data structure.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define your custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>IntMap</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
--   <a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)

-- | &lt;math&gt;. The function <tt><a>mapAccum</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumWithKey</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumRWithKey</a></tt> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has slightly better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: IntMap a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: IntMap a -> [Key]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Returns all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
--   keysSet empty == Data.IntSet.empty
--   </pre>
keysSet :: IntMap a -> IntSet

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Filter all values that satisfy some predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys that satisfy some predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys/values that satisfy some predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. The restriction of a map to the keys in a set.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   </pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Remove all the keys in a given set from a map.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   </pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all
--   <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partitionWithKey</a> (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower than
--   <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot key was found in the original map.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | &lt;math&gt;. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
--   returns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
--   when <tt>f</tt> returns <a>True</a> when applied to their respective
--   values. For example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   </pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
findMin :: IntMap a -> (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
findMax :: IntMap a -> (Key, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMin :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMax :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete and find the minimal element. This function
--   throws an error if the map is empty. Use <a>minViewWithKey</a> if the
--   map may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Delete and find the maximal element. This function
--   throws an error if the map is empty. Use <a>maxViewWithKey</a> if the
--   map may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Retrieves the minimal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the maximal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)


-- | <h1>Finite Int Maps (strict interface)</h1>
--   
--   The <tt><a>IntMap</a> v</tt> type represents a finite map (sometimes
--   called a dictionary) from key of type <tt>Int</tt> to values of type
--   <tt>v</tt>.
--   
--   Each function in this module is careful to force values before
--   installing them in an <a>IntMap</a>. This is usually more efficient
--   when laziness is not necessary. When laziness <i>is</i> required, use
--   the functions in <a>Data.IntMap.Lazy</a>.
--   
--   In particular, the functions in this module obey the following law:
--   
--   <ul>
--   <li>If all values stored in all maps in the arguments are in WHNF,
--   then all values stored in all maps in the results will be in WHNF once
--   those maps are evaluated.</li>
--   </ul>
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap.Strict (IntMap)
--   import qualified Data.IntMap.Strict as IntMap
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Warning</h2>
--   
--   The <a>IntMap</a> type is shared between the lazy and strict modules,
--   meaning that the same <a>IntMap</a> value can be passed to functions
--   in both modules. This means that the <tt>Functor</tt>,
--   <tt>Traversable</tt> and <a>Data</a> instances are the same as for the
--   <a>Data.IntMap.Lazy</a> module, so if they are used the resulting map
--   may contain suspended values (thunks).
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced map implementation (see
--   <a>Data.Map</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   Operation comments contain the operation time complexity in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map and &lt;math&gt; referring to the number of bits in an
--   <tt>Int</tt> (32 or 64).
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> have a
--   worst-case complexity of &lt;math&gt;. This means that the operation
--   can become linear in the number of elements with a maximum of
--   &lt;math&gt; -- the number of bits in an <tt>Int</tt> (32 or 64).
--   These peculiar asymptotics are determined by the depth of the Patricia
--   trees:
--   
--   <ul>
--   <li>even for an extremely unbalanced tree, the depth cannot be larger
--   than the number of elements &lt;math&gt;,</li>
--   <li>each level of a Patricia tree determines at least one more bit
--   shared by all subelements, so there could not be more than
--   &lt;math&gt; levels.</li>
--   </ul>
--   
--   If all &lt;math&gt; keys in the tree are between 0 and &lt;math&gt;
--   (or, say, between &lt;math&gt; and &lt;math&gt;), the estimate can be
--   refined to &lt;math&gt;. If the set of keys is sufficiently "dense",
--   this becomes &lt;math&gt; or simply the familiar &lt;math&gt;,
--   matching balanced binary trees.
--   
--   The most performant scenario for <a>IntMap</a> are keys from a
--   contiguous subset, in which case the complexity is proportional to
--   &lt;math&gt;, capped by &lt;math&gt;. The worst scenario are
--   exponentially growing keys &lt;math&gt;, for which complexity grows as
--   fast as &lt;math&gt; but again is capped by &lt;math&gt;.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
--   
--   Benchmarks comparing <a>Data.IntMap.Strict</a> with other dictionary
--   implementations can be found at
--   <a>https://github.com/haskell-perf/dictionaries</a>.
module Data.IntMap.Strict

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | &lt;math&gt;. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.IntSet.empty == empty
--   </pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | &lt;math&gt;. Create a map from a list of key/value pairs.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also fromAscListWithKey'.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   </pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order and all distinct.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Insert a new key/value pair in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value, i.e. <a>insert</a> is equivalent to
--   <tt><a>insertWith</a> <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function. <tt><a>insertWith</a>
--   f key value mp</tt> will insert the pair (key, value) into <tt>mp</tt>
--   if key does not exist in the map. If the key does exist, the function
--   will insert <tt>f new_value old_value</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function.
--   <tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert <tt>f key new_value
--   old_value</tt>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   If the key exists in the map, this function is lazy in <tt>value</tt>
--   but strict in the result of <tt>f</tt>.
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>insertLookupWithKey</a> f k x
--   map</tt>) is a pair where the first element is equal to
--   (<tt><a>lookup</a> k map</tt>) and the second element equal to
--   (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f k
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Look up and update. The function returns original value,
--   if it is updated. This is different behavior than
--   <a>updateLookupWithKey</a>. Returns the original key value if the map
--   entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in an <a>IntMap</a>.
--   In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a>
--   k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in an
--   <a>IntMap</a>. In short : <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a>
--   f k m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | &lt;math&gt;. Look up the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] !? 1 == Nothing
--   fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: IntMap a -> Key -> a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
--   when the key is not an element of the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | &lt;math&gt;. Is the key a member of the map?
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map?
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | &lt;math&gt;. Number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: IntMap a -> Int

-- | &lt;math&gt;. The (left-biased) union of two maps. It prefers the
--   first map when duplicate keys are encountered, i.e. (<tt><a>union</a>
--   == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: Foldable f => f (IntMap a) -> IntMap a

-- | The union of a list of maps, with a combining operation.
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: Foldable f => (a -> a -> a) -> f (IntMap a) -> IntMap a

-- | &lt;math&gt;. Difference between two maps (based on keys).
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | &lt;math&gt;. Difference with a combining function.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The (left-biased) intersection of two maps (based on
--   keys).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e. their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   disjoint a b == null (intersection a b)
--   </pre>
disjoint :: IntMap a -> IntMap b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.IntMap.Strict</a> exposed a
--   version of <a>compose</a> that forced the values of the output
--   <a>IntMap</a>. This version does not force these values.
compose :: IntMap c -> IntMap Int -> IntMap c

-- | &lt;math&gt;. A high-performance universal combining function. Using
--   <a>mergeWithKey</a>, all combining functions can be defined without
--   any loss of efficiency (with exception of <a>union</a>,
--   <a>difference</a> and <a>intersection</a>, where sharing of some nodes
--   is lost with <a>mergeWithKey</a>).
--   
--   <b>Warning</b>: Please make sure you know what is going on when using
--   <a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
--   growth or even corruption of the data structure.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define your custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>IntMap</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
--   <a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)

-- | &lt;math&gt;. The function <tt><a>mapAccum</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumWithKey</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumRWithKey</a></tt> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has slightly better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: IntMap a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: IntMap a -> [Key]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Returns all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
--   keysSet empty == Data.IntSet.empty
--   </pre>
keysSet :: IntMap a -> IntSet

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Filter all values that satisfy some predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys that satisfy some predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys/values that satisfy some predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. The restriction of a map to the keys in a set.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   </pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Remove all the keys in a given set from a map.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   </pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all
--   <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partitionWithKey</a> (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower than
--   <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot key was found in the original map.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | &lt;math&gt;. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
--   returns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
--   when <tt>f</tt> returns <a>True</a> when applied to their respective
--   values. For example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   </pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
findMin :: IntMap a -> (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
findMax :: IntMap a -> (Key, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMin :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMax :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete and find the minimal element. This function
--   throws an error if the map is empty. Use <a>minViewWithKey</a> if the
--   map may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Delete and find the maximal element. This function
--   throws an error if the map is empty. Use <a>maxViewWithKey</a> if the
--   map may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Retrieves the minimal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the maximal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)


-- | This module defines an API for writing functions that merge two maps.
--   The key functions are <a>merge</a> and <a>mergeA</a>. Each of these
--   can be used with several different "merge tactics".
--   
--   The <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
--   and strict modules. Only the choice of merge tactics determines
--   strictness. If you use <a>mapMissing</a> from this module then the
--   results will be forced before they are inserted. If you use
--   <a>mapMissing</a> from <a>Data.Map.Merge.Lazy</a> then they will not.
--   
--   <h2>Efficiency note</h2>
--   
--   The <a>Category</a>, <a>Applicative</a>, and <a>Monad</a> instances
--   for <a>WhenMissing</a> tactics are included because they are valid.
--   However, they are inefficient in many cases and should usually be
--   avoided. The instances for <a>WhenMatched</a> tactics should not pose
--   any major efficiency problems.
module Data.IntMap.Merge.Strict

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; Maybe
--   z</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
--   Maybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge diffPreserve diffDrop f
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
--   </pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched :: (k -&gt; x -&gt; y -&gt; Maybe z)
--                       -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched :: (k -&gt; x -&gt; y -&gt; z)
--                  -&gt; SimpleWhenMatched k x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (k -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) x y. Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) x. Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing k x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) x. Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMissing f k x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
--   z)</tt>.
data WhenMissing (f :: Type -> Type) x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMatched f x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
data WhenMatched (f :: Type -> Type) x y z

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3,'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>mergeA</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: Applicative f => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: Applicative f => (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f k x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b x. Functor f => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f k x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)


-- | This module defines an API for writing functions that merge two maps.
--   The key functions are <a>merge</a> and <a>mergeA</a>. Each of these
--   can be used with several different "merge tactics".
--   
--   The <a>merge</a> and <a>mergeA</a> functions are shared by the lazy
--   and strict modules. Only the choice of merge tactics determines
--   strictness. If you use <a>mapMissing</a> from
--   <a>Data.Map.Merge.Strict</a> then the results will be forced before
--   they are inserted. If you use <a>mapMissing</a> from this module then
--   they will not.
--   
--   <h2>Efficiency note</h2>
--   
--   The <a>Category</a>, <a>Applicative</a>, and <a>Monad</a> instances
--   for <a>WhenMissing</a> tactics are included because they are valid.
--   However, they are inefficient in many cases and should usually be
--   avoided. The instances for <a>WhenMatched</a> tactics should not pose
--   any major efficiency problems.
module Data.IntMap.Merge.Lazy

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMissing x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; Maybe
--   z</tt>.
type SimpleWhenMissing = WhenMissing Identity

-- | A tactic for dealing with keys present in both maps in <a>merge</a>.
--   
--   A tactic of type <tt>SimpleWhenMatched x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt;
--   Maybe z</tt>.
type SimpleWhenMatched = WhenMatched Identity

-- | Merge two maps.
--   
--   <a>merge</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>mapMaybeMissing</a> and <a>zipWithMaybeMatched</a>.
--   
--   Consider
--   
--   <pre>
--   merge (mapMaybeMissing g1)
--                (mapMaybeMissing g2)
--                (zipWithMaybeMatched f)
--                m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3, 'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>merge</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   maybes = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   This produces a <a>Maybe</a> for each key:
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>mapMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   </ul>
--   
--   When <a>merge</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should typically use
--   <a>merge</a> to define your custom combining functions.
--   
--   Examples:
--   
--   <pre>
--   unionWithKey f = merge preserveMissing preserveMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   intersectionWithKey f = merge dropMissing dropMissing (zipWithMatched f)
--   </pre>
--   
--   <pre>
--   differenceWith f = merge diffPreserve diffDrop f
--   </pre>
--   
--   <pre>
--   symmetricDifference = merge diffPreserve diffPreserve (\ _ _ _ -&gt; Nothing)
--   </pre>
--   
--   <pre>
--   mapEachPiece f g h = merge (diffMapWithKey f) (diffMapWithKey g)
--   </pre>
merge :: SimpleWhenMissing a c -> SimpleWhenMissing b c -> SimpleWhenMatched a b c -> IntMap a -> IntMap b -> IntMap c

-- | When a key is found in both maps, apply a function to the key and
--   values and maybe use the result in the merged map.
--   
--   <pre>
--   zipWithMaybeMatched
--     :: (Key -&gt; x -&gt; y -&gt; Maybe z)
--     -&gt; SimpleWhenMatched x y z
--   </pre>
zipWithMaybeMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> Maybe z) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values and use the result in the merged map.
--   
--   <pre>
--   zipWithMatched
--     :: (Key -&gt; x -&gt; y -&gt; z)
--     -&gt; SimpleWhenMatched x y z
--   </pre>
zipWithMatched :: forall (f :: Type -> Type) x y z. Applicative f => (Key -> x -> y -> z) -> WhenMatched f x y z

-- | Map over the entries whose keys are missing from the other map,
--   optionally removing some. This is the most powerful
--   <a>SimpleWhenMissing</a> tactic, but others are usually more
--   efficient.
--   
--   <pre>
--   mapMaybeMissing :: (Key -&gt; x -&gt; Maybe y) -&gt; SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   mapMaybeMissing f = traverseMaybeMissing (\k x -&gt; pure (f k x))
--   </pre>
--   
--   but <tt>mapMaybeMissing</tt> uses fewer unnecessary <a>Applicative</a>
--   operations.
mapMaybeMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> Maybe y) -> WhenMissing f x y

-- | Drop all the entries whose keys are missing from the other map.
--   
--   <pre>
--   dropMissing :: SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   dropMissing = mapMaybeMissing (\_ _ -&gt; Nothing)
--   </pre>
--   
--   but <tt>dropMissing</tt> is much faster.
dropMissing :: forall (f :: Type -> Type) x y. Applicative f => WhenMissing f x y

-- | Preserve, unchanged, the entries whose keys are missing from the other
--   map.
--   
--   <pre>
--   preserveMissing :: SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   preserveMissing = Merge.Lazy.mapMaybeMissing (\_ x -&gt; Just x)
--   </pre>
--   
--   but <tt>preserveMissing</tt> is much faster.
preserveMissing :: forall (f :: Type -> Type) x. Applicative f => WhenMissing f x x

-- | Map over the entries whose keys are missing from the other map.
--   
--   <pre>
--   mapMissing :: (k -&gt; x -&gt; y) -&gt; SimpleWhenMissing x y
--   </pre>
--   
--   <pre>
--   mapMissing f = mapMaybeMissing (\k x -&gt; Just $ f k x)
--   </pre>
--   
--   but <tt>mapMissing</tt> is somewhat faster.
mapMissing :: forall (f :: Type -> Type) x y. Applicative f => (Key -> x -> y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map.
--   
--   <pre>
--   filterMissing :: (k -&gt; x -&gt; Bool) -&gt; SimpleWhenMissing x x
--   </pre>
--   
--   <pre>
--   filterMissing f = Merge.Lazy.mapMaybeMissing $ \k x -&gt; guard (f k x) *&gt; Just x
--   </pre>
--   
--   but this should be a little faster.
filterMissing :: forall (f :: Type -> Type) x. Applicative f => (Key -> x -> Bool) -> WhenMissing f x x

-- | A tactic for dealing with keys present in one map but not the other in
--   <a>merge</a> or <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMissing f k x z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; f (Maybe
--   z)</tt>.
data WhenMissing (f :: Type -> Type) x y

-- | A tactic for dealing with keys present in both maps in <a>merge</a> or
--   <a>mergeA</a>.
--   
--   A tactic of type <tt>WhenMatched f x y z</tt> is an abstract
--   representation of a function of type <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
data WhenMatched (f :: Type -> Type) x y z

-- | An applicative version of <a>merge</a>.
--   
--   <a>mergeA</a> takes two <a>WhenMissing</a> tactics, a
--   <a>WhenMatched</a> tactic and two maps. It uses the tactics to merge
--   the maps. Its behavior is best understood via its fundamental tactics,
--   <a>traverseMaybeMissing</a> and <a>zipWithMaybeAMatched</a>.
--   
--   Consider
--   
--   <pre>
--   mergeA (traverseMaybeMissing g1)
--                 (traverseMaybeMissing g2)
--                 (zipWithMaybeAMatched f)
--                 m1 m2
--   </pre>
--   
--   Take, for example,
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'), (3,'c'), (4, 'd')]
--   m2 = [(1, "one"), (2, "two"), (4, "three")]
--   </pre>
--   
--   <a>mergeA</a> will first "align" these maps by key:
--   
--   <pre>
--   m1 = [(0, 'a'), (1, 'b'),               (3, 'c'), (4, 'd')]
--   m2 =           [(1, "one"), (2, "two"),           (4, "three")]
--   </pre>
--   
--   It will then pass the individual entries and pairs of entries to
--   <tt>g1</tt>, <tt>g2</tt>, or <tt>f</tt> as appropriate:
--   
--   <pre>
--   actions = [g1 0 'a', f 1 'b' "one", g2 2 "two", g1 3 'c', f 4 'd' "three"]
--   </pre>
--   
--   Next, it will perform the actions in the <tt>actions</tt> list in
--   order from left to right.
--   
--   <pre>
--   keys =     0        1          2           3        4
--   results = [Nothing, Just True, Just False, Nothing, Just True]
--   </pre>
--   
--   Finally, the <tt>Just</tt> results are collected into a map:
--   
--   <pre>
--   return value = [(1, True), (2, False), (4, True)]
--   </pre>
--   
--   The other tactics below are optimizations or simplifications of
--   <a>traverseMaybeMissing</a> for special cases. Most importantly,
--   
--   <ul>
--   <li><a>dropMissing</a> drops all the keys.</li>
--   <li><a>preserveMissing</a> leaves all the entries alone.</li>
--   <li><a>mapMaybeMissing</a> does not use the <a>Applicative</a>
--   context.</li>
--   </ul>
--   
--   When <a>mergeA</a> is given three arguments, it is inlined at the call
--   site. To prevent excessive inlining, you should generally only use
--   <a>mergeA</a> to define custom combining functions.
mergeA :: Applicative f => WhenMissing f a c -> WhenMissing f b c -> WhenMatched f a b c -> IntMap a -> IntMap b -> f (IntMap c)

-- | When a key is found in both maps, apply a function to the key and
--   values, perform the resulting action, and maybe use the result in the
--   merged map.
--   
--   This is the fundamental <a>WhenMatched</a> tactic.
zipWithMaybeAMatched :: (Key -> x -> y -> f (Maybe z)) -> WhenMatched f x y z

-- | When a key is found in both maps, apply a function to the key and
--   values to produce an action and use its result in the merged map.
zipWithAMatched :: Applicative f => (Key -> x -> y -> f z) -> WhenMatched f x y z

-- | Traverse over the entries whose keys are missing from the other map,
--   optionally producing values to put in the result. This is the most
--   powerful <a>WhenMissing</a> tactic, but others are usually more
--   efficient.
traverseMaybeMissing :: Applicative f => (Key -> x -> f (Maybe y)) -> WhenMissing f x y

-- | Traverse over the entries whose keys are missing from the other map.
traverseMissing :: Applicative f => (Key -> x -> f y) -> WhenMissing f x y

-- | Filter the entries whose keys are missing from the other map using
--   some <a>Applicative</a> action.
--   
--   <pre>
--   filterAMissing f = Merge.Lazy.traverseMaybeMissing $
--     \k x -&gt; (\b -&gt; guard b *&gt; Just x) &lt;$&gt; f k x
--   </pre>
--   
--   but this should be a little faster.
filterAMissing :: Applicative f => (Key -> x -> f Bool) -> WhenMissing f x x

-- | Map covariantly over a <tt><a>WhenMissing</a> f x</tt>.
mapWhenMissing :: forall (f :: Type -> Type) a b x. (Applicative f, Monad f) => (a -> b) -> WhenMissing f x a -> WhenMissing f x b

-- | Map covariantly over a <tt><a>WhenMatched</a> f x y</tt>.
mapWhenMatched :: forall (f :: Type -> Type) a b x y. Functor f => (a -> b) -> WhenMatched f x y a -> WhenMatched f x y b

-- | Map contravariantly over a <tt><a>WhenMissing</a> f _ x</tt>.
lmapWhenMissing :: forall b a (f :: Type -> Type) x. (b -> a) -> WhenMissing f a x -> WhenMissing f b x

-- | Map contravariantly over a <tt><a>WhenMatched</a> f _ y z</tt>.
contramapFirstWhenMatched :: forall b a (f :: Type -> Type) y z. (b -> a) -> WhenMatched f a y z -> WhenMatched f b y z

-- | Map contravariantly over a <tt><a>WhenMatched</a> f x _ z</tt>.
contramapSecondWhenMatched :: forall b a (f :: Type -> Type) x z. (b -> a) -> WhenMatched f x a z -> WhenMatched f x b z

-- | Along with zipWithMaybeAMatched, witnesses the isomorphism between
--   <tt>WhenMatched f x y z</tt> and <tt>Key -&gt; x -&gt; y -&gt; f
--   (Maybe z)</tt>.
runWhenMatched :: WhenMatched f x y z -> Key -> x -> y -> f (Maybe z)

-- | Along with traverseMaybeMissing, witnesses the isomorphism between
--   <tt>WhenMissing f x y</tt> and <tt>Key -&gt; x -&gt; f (Maybe y)</tt>.
runWhenMissing :: WhenMissing f x y -> Key -> x -> f (Maybe y)


-- | <h1>Finite Int Maps (lazy interface)</h1>
--   
--   The <tt><a>IntMap</a> v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>Int</tt> to values of type
--   <tt>v</tt>.
--   
--   The functions in <a>Data.IntMap.Strict</a> are careful to force values
--   before installing them in an <a>IntMap</a>. This is usually more
--   efficient in cases where laziness is not essential. The functions in
--   this module do not do so.
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap.Lazy (IntMap)
--   import qualified Data.IntMap.Lazy as IntMap
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced map implementation (see
--   <a>Data.Map</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   Operation comments contain the operation time complexity in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map and &lt;math&gt; referring to the number of bits in an
--   <a>Int</a> (32 or 64).
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> have a
--   worst-case complexity of &lt;math&gt;. This means that the operation
--   can become linear in the number of elements with a maximum of
--   &lt;math&gt; -- the number of bits in an <a>Int</a> (32 or 64). These
--   peculiar asymptotics are determined by the depth of the Patricia
--   trees:
--   
--   <ul>
--   <li>even for an extremely unbalanced tree, the depth cannot be larger
--   than the number of elements &lt;math&gt;,</li>
--   <li>each level of a Patricia tree determines at least one more bit
--   shared by all subelements, so there could not be more than
--   &lt;math&gt; levels.</li>
--   </ul>
--   
--   If all &lt;math&gt; keys in the tree are between 0 and &lt;math&gt;
--   (or, say, between &lt;math&gt; and &lt;math&gt;), the estimate can be
--   refined to &lt;math&gt;. If the set of keys is sufficiently "dense",
--   this becomes &lt;math&gt; or simply the familiar &lt;math&gt;,
--   matching balanced binary trees.
--   
--   The most performant scenario for <a>IntMap</a> are keys from a
--   contiguous subset, in which case the complexity is proportional to
--   &lt;math&gt;, capped by &lt;math&gt;. The worst scenario are
--   exponentially growing keys &lt;math&gt;, for which complexity grows as
--   fast as &lt;math&gt; but again is capped by &lt;math&gt;.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
--   
--   Benchmarks comparing <a>Data.IntMap.Lazy</a> with other dictionary
--   implementations can be found at
--   <a>https://github.com/haskell-perf/dictionaries</a>.
module Data.IntMap.Lazy

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | &lt;math&gt;. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | &lt;math&gt;. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | &lt;math&gt;. Build a map from a set of keys and a function which for
--   each key computes its value.
--   
--   <pre>
--   fromSet (\k -&gt; replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
--   fromSet undefined Data.IntSet.empty == empty
--   </pre>
fromSet :: (Key -> a) -> IntSet -> IntMap a

-- | &lt;math&gt;. Create a map from a list of key/value pairs.
--   
--   <pre>
--   fromList [] == empty
--   fromList [(5,"a"), (3,"b"), (5, "c")] == fromList [(5,"c"), (3,"b")]
--   fromList [(5,"c"), (3,"b"), (5, "a")] == fromList [(5,"a"), (3,"b")]
--   </pre>
fromList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWith</a>.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"x"), (5,"c")] == fromList [(3, "x"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
--   
--   Note the reverse ordering of <tt>"cba"</tt> in the example.
--   
--   The symmetric combining function <tt>f</tt> is applied in a left-fold
--   over the list, as <tt>f new old</tt>.
--   
--   <h3>Performance</h3>
--   
--   You should ensure that the given <tt>f</tt> is fast with this order of
--   arguments.
--   
--   Symmetric functions may be slow in one order, and fast in another. For
--   the common case of collecting values of matching keys in a list, as
--   above:
--   
--   The complexity of <tt>(++) a b</tt> is &lt;math&gt;, so it is fast
--   when given a short list as its first argument. Thus:
--   
--   <pre>
--   fromListWith       (++)  (replicate 1000000 (3, "x"))   -- O(n),  fast
--   fromListWith (flip (++)) (replicate 1000000 (3, "x"))   -- O(n²), extremely slow
--   </pre>
--   
--   because they evaluate as, respectively:
--   
--   <pre>
--   fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))]   -- O(n)
--   fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")]   -- O(n²)
--   </pre>
--   
--   Thus, to get good performance with an operation like <tt>(++)</tt>
--   while also preserving the same order as in the input list, reverse the
--   input:
--   
--   <pre>
--   fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
--   </pre>
--   
--   and it is always fast to combine singleton-list values <tt>[v]</tt>
--   with <tt>fromListWith (++)</tt>, as in:
--   
--   <pre>
--   fromListWith (++) $ reverse $ map (\(k, v) -&gt; (k, [v])) someListOfTuples
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs with a
--   combining function. See also fromAscListWithKey'.
--   
--   <pre>
--   let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
--   fromListWithKey f [] == empty
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscList [(3,"b"), (5,"a")]          == fromList [(3, "b"), (5, "a")]
--   fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")]
--   </pre>
fromAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWith</a> if the precondition may not hold.
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order, with a combining function on equal keys.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   non-decreasing order. This precondition is not checked. Use
--   <a>fromListWithKey</a> if the precondition may not hold.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Build a map from a list of key/value pairs where the
--   keys are in ascending order and all distinct.
--   
--   <b>Warning</b>: This function should be used only if the keys are in
--   strictly increasing order. This precondition is not checked. Use
--   <a>fromList</a> if the precondition may not hold.
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | &lt;math&gt;. Insert a new key/value pair in the map. If the key is
--   already present in the map, the associated value is replaced with the
--   supplied value, i.e. <a>insert</a> is equivalent to
--   <tt><a>insertWith</a> <a>const</a></tt>.
--   
--   <pre>
--   insert 5 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'x')]
--   insert 7 'x' (fromList [(5,'a'), (3,'b')]) == fromList [(3, 'b'), (5, 'a'), (7, 'x')]
--   insert 5 'x' empty                         == singleton 5 'x'
--   </pre>
insert :: Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function. <tt><a>insertWith</a>
--   f key value mp</tt> will insert the pair (key, value) into <tt>mp</tt>
--   if key does not exist in the map. If the key does exist, the function
--   will insert <tt>f new_value old_value</tt>.
--   
--   <pre>
--   insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
--   insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWith (++) 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Insert with a combining function.
--   <tt><a>insertWithKey</a> f key value mp</tt> will insert the pair
--   (key, value) into <tt>mp</tt> if key does not exist in the map. If the
--   key does exist, the function will insert <tt>f key new_value
--   old_value</tt>.
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
--   insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
--   insertWithKey f 5 "xxx" empty                         == singleton 5 "xxx"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>insertLookupWithKey</a> f k x
--   map</tt>) is a pair where the first element is equal to
--   (<tt><a>lookup</a> k map</tt>) and the second element equal to
--   (<tt><a>insertWithKey</a> f k x map</tt>).
--   
--   <pre>
--   let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
--   insertLookupWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:xxx|a")])
--   insertLookupWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "xxx")])
--   insertLookupWithKey f 5 "xxx" empty                         == (Nothing,  singleton 5 "xxx")
--   </pre>
--   
--   This is how to define <tt>insertLookup</tt> using
--   <tt>insertLookupWithKey</tt>:
--   
--   <pre>
--   let insertLookup kx x t = insertLookupWithKey (\_ a _ -&gt; a) kx x t
--   insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
--   insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a"), (7, "x")])
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. Delete a key and its value from the map. When the key is
--   not a member of the map, the original map is returned.
--   
--   <pre>
--   delete 5 (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   delete 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   delete 5 empty                         == empty
--   </pre>
delete :: Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   adjust ("new " ++) 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   adjust ("new " ++) 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjust ("new " ++) 7 empty                         == empty
--   </pre>
adjust :: (a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Adjust a value at a specific key. When the key is not a
--   member of the map, the original map is returned.
--   
--   <pre>
--   let f key x = (show key) ++ ":new " ++ x
--   adjustWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   adjustWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   adjustWithKey f 7 empty                         == empty
--   </pre>
adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   update f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "new a")]
--   update f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   update f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>update</a> f k map</tt>) updates
--   the value <tt>x</tt> at <tt>k</tt> (if it is in the map). If (<tt>f k
--   x</tt>) is <a>Nothing</a>, the element is deleted. If it is
--   (<tt><a>Just</a> y</tt>), the key <tt>k</tt> is bound to the new value
--   <tt>y</tt>.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateWithKey f 5 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:new a")]
--   updateWithKey f 7 (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a")]
--   updateWithKey f 3 (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. Look up and update. This function returns the original
--   value, if it is updated. This is different behavior than
--   <a>updateLookupWithKey</a>. Returns the original key value if the map
--   entry is deleted.
--   
--   <pre>
--   let f k x = if x == "a" then Just ((show k) ++ ":new a") else Nothing
--   updateLookupWithKey f 5 (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "5:new a")])
--   updateLookupWithKey f 7 (fromList [(5,"a"), (3,"b")]) == (Nothing,  fromList [(3, "b"), (5, "a")])
--   updateLookupWithKey f 3 (fromList [(5,"a"), (3,"b")]) == (Just "b", singleton 5 "a")
--   </pre>
updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a, IntMap a)

-- | &lt;math&gt;. The expression (<tt><a>alter</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a>
--   can be used to insert, delete, or update a value in an <a>IntMap</a>.
--   In short : <tt><a>lookup</a> k (<a>alter</a> f k m) = f (<a>lookup</a>
--   k m)</tt>.
alter :: (Maybe a -> Maybe a) -> Key -> IntMap a -> IntMap a

-- | &lt;math&gt;. The expression (<tt><a>alterF</a> f k map</tt>) alters
--   the value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alterF</a>
--   can be used to inspect, insert, delete, or update a value in an
--   <a>IntMap</a>. In short : <tt><a>lookup</a> k &lt;$&gt; <a>alterF</a>
--   f k m = f (<a>lookup</a> k m)</tt>.
--   
--   Example:
--   
--   <pre>
--   interactiveAlter :: Int -&gt; IntMap String -&gt; IO (IntMap String)
--   interactiveAlter k m = alterF f k m where
--     f Nothing = do
--        putStrLn $ show k ++
--            " was not found in the map. Would you like to add it?"
--        getUserResponse1 :: IO (Maybe String)
--     f (Just old) = do
--        putStrLn $ "The key is currently bound to " ++ show old ++
--            ". Would you like to change or delete it?"
--        getUserResponse2 :: IO (Maybe String)
--   </pre>
--   
--   <a>alterF</a> is the most general operation for working with an
--   individual key that may or may not be in a given map.
--   
--   Note: <a>alterF</a> is a flipped version of the <tt>at</tt> combinator
--   from <tt>Control.Lens.At</tt>.
alterF :: Functor f => (Maybe a -> f (Maybe a)) -> Key -> IntMap a -> f (IntMap a)

-- | &lt;math&gt;. Look up the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | &lt;math&gt;. Find the value at a key. Returns <a>Nothing</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] !? 1 == Nothing
--   fromList [(5,'a'), (3,'b')] !? 5 == Just 'a'
--   </pre>
(!?) :: IntMap a -> Key -> Maybe a
infixl 9 !?

-- | &lt;math&gt;. Find the value at a key. Calls <a>error</a> when the
--   element can not be found.
--   
--   <pre>
--   fromList [(5,'a'), (3,'b')] ! 1    Error: element not in the map
--   fromList [(5,'a'), (3,'b')] ! 5 == 'a'
--   </pre>
(!) :: IntMap a -> Key -> a

-- | &lt;math&gt;. The expression <tt>(<a>findWithDefault</a> def k
--   map)</tt> returns the value at key <tt>k</tt> or returns <tt>def</tt>
--   when the key is not an element of the map.
--   
--   <pre>
--   findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
--   findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'
--   </pre>
findWithDefault :: a -> Key -> IntMap a -> a

-- | &lt;math&gt;. Is the key a member of the map?
--   
--   <pre>
--   member 5 (fromList [(5,'a'), (3,'b')]) == True
--   member 1 (fromList [(5,'a'), (3,'b')]) == False
--   </pre>
member :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Is the key not a member of the map?
--   
--   <pre>
--   notMember 5 (fromList [(5,'a'), (3,'b')]) == False
--   notMember 1 (fromList [(5,'a'), (3,'b')]) == True
--   </pre>
notMember :: Key -> IntMap a -> Bool

-- | &lt;math&gt;. Find largest key smaller than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLT 3 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLT 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   </pre>
lookupLT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater than the given one and return
--   the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGT 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGT 5 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGT :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find largest key smaller or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupLE 2 (fromList [(3,'a'), (5,'b')]) == Nothing
--   lookupLE 4 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupLE 5 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   </pre>
lookupLE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Find smallest key greater or equal to the given one and
--   return the corresponding (key, value) pair.
--   
--   <pre>
--   lookupGE 3 (fromList [(3,'a'), (5,'b')]) == Just (3, 'a')
--   lookupGE 4 (fromList [(3,'a'), (5,'b')]) == Just (5, 'b')
--   lookupGE 6 (fromList [(3,'a'), (5,'b')]) == Nothing
--   </pre>
lookupGE :: Key -> IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | &lt;math&gt;. Number of elements in the map.
--   
--   <pre>
--   size empty                                   == 0
--   size (singleton 1 'a')                       == 1
--   size (fromList([(1,'a'), (2,'c'), (3,'b')])) == 3
--   </pre>
size :: IntMap a -> Int

-- | &lt;math&gt;. The (left-biased) union of two maps. It prefers the
--   first map when duplicate keys are encountered, i.e. (<tt><a>union</a>
--   == <a>unionWith</a> <a>const</a></tt>).
--   
--   <pre>
--   union (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "a"), (7, "C")]
--   </pre>
union :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. The union with a combining function.
--   
--   <pre>
--   let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
--   unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | The union of a list of maps.
--   
--   <pre>
--   unions [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "b"), (5, "a"), (7, "C")]
--   unions [(fromList [(5, "A3"), (3, "B3")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "a"), (3, "b")])]
--       == fromList [(3, "B3"), (5, "A3"), (7, "C")]
--   </pre>
unions :: Foldable f => f (IntMap a) -> IntMap a

-- | The union of a list of maps, with a combining operation.
--   
--   <pre>
--   unionsWith (++) [(fromList [(5, "a"), (3, "b")]), (fromList [(5, "A"), (7, "C")]), (fromList [(5, "A3"), (3, "B3")])]
--       == fromList [(3, "bB3"), (5, "aAA3"), (7, "C")]
--   </pre>
unionsWith :: Foldable f => (a -> a -> a) -> f (IntMap a) -> IntMap a

-- | &lt;math&gt;. Difference between two maps (based on keys).
--   
--   <pre>
--   difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
--   </pre>
difference :: IntMap a -> IntMap b -> IntMap a

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a
infixl 9 \\

-- | &lt;math&gt;. Difference with a combining function.
--   
--   <pre>
--   let f al ar = if al == "b" then Just (al ++ ":" ++ ar) else Nothing
--   differenceWith f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (7, "C")])
--       == singleton 3 "b:B"
--   </pre>
differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. 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 <a>Nothing</a>, the element is discarded
--   (proper set difference). If it returns (<tt><a>Just</a> y</tt>), the
--   element is updated with a new value <tt>y</tt>.
--   
--   <pre>
--   let f k al ar = if al == "b" then Just ((show k) ++ ":" ++ al ++ "|" ++ ar) else Nothing
--   differenceWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (3, "B"), (10, "C")])
--       == singleton 3 "3:b|B"
--   </pre>
differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The (left-biased) intersection of two maps (based on
--   keys).
--   
--   <pre>
--   intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "a"
--   </pre>
intersection :: IntMap a -> IntMap b -> IntMap a

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"
--   </pre>
intersectionWith :: (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The intersection with a combining function.
--   
--   <pre>
--   let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
--   intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
--   </pre>
intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. The symmetric difference of two maps.
--   
--   The result contains entries whose keys appear in exactly one of the
--   two maps.
--   
--   <pre>
--   symmetricDifference
--     (fromList [(0,'q'),(2,'b'),(4,'w'),(6,'o')])
--     (fromList [(0,'e'),(3,'r'),(6,'t'),(9,'s')])
--   ==
--   fromList [(2,'b'),(3,'r'),(4,'w'),(9,'s')]
--   </pre>
symmetricDifference :: IntMap a -> IntMap a -> IntMap a

-- | &lt;math&gt;. Check whether the key sets of two maps are disjoint
--   (i.e. their <a>intersection</a> is empty).
--   
--   <pre>
--   disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())])   == True
--   disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False
--   disjoint (fromList [])        (fromList [])                 == True
--   </pre>
--   
--   <pre>
--   disjoint a b == null (intersection a b)
--   </pre>
disjoint :: IntMap a -> IntMap b -> Bool

-- | Relate the keys of one map to the values of the other, by using the
--   values of the former as keys for lookups in the latter.
--   
--   Complexity: &lt;math&gt;, where &lt;math&gt; is the size of the first
--   argument
--   
--   <pre>
--   compose (fromList [('a', "A"), ('b', "B")]) (fromList [(1,'a'),(2,'b'),(3,'z')]) = fromList [(1,"A"),(2,"B")]
--   </pre>
--   
--   <pre>
--   (<a>compose</a> bc ab <a>!?</a>) = (bc <a>!?</a>) &lt;=&lt; (ab <a>!?</a>)
--   </pre>
--   
--   <b>Note:</b> Prior to v0.6.4, <a>Data.IntMap.Strict</a> exposed a
--   version of <a>compose</a> that forced the values of the output
--   <a>IntMap</a>. This version does not force these values.
compose :: IntMap c -> IntMap Int -> IntMap c

-- | &lt;math&gt;. A high-performance universal combining function. Using
--   <a>mergeWithKey</a>, all combining functions can be defined without
--   any loss of efficiency (with exception of <a>union</a>,
--   <a>difference</a> and <a>intersection</a>, where sharing of some nodes
--   is lost with <a>mergeWithKey</a>).
--   
--   <b>Warning</b>: Please make sure you know what is going on when using
--   <a>mergeWithKey</a>, otherwise you can be surprised by unexpected code
--   growth or even corruption of the data structure.
--   
--   When <a>mergeWithKey</a> is given three arguments, it is inlined to
--   the call site. You should therefore use <a>mergeWithKey</a> only to
--   define your custom combining functions. For example, you could define
--   <a>unionWithKey</a>, <a>differenceWithKey</a> and
--   <a>intersectionWithKey</a> as
--   
--   <pre>
--   myUnionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) id id m1 m2
--   myDifferenceWithKey f m1 m2 = mergeWithKey f id (const empty) m1 m2
--   myIntersectionWithKey f m1 m2 = mergeWithKey (\k x1 x2 -&gt; Just (f k x1 x2)) (const empty) (const empty) m1 m2
--   </pre>
--   
--   When calling <tt><a>mergeWithKey</a> combine only1 only2</tt>, a
--   function combining two <a>IntMap</a>s is created, such that
--   
--   <ul>
--   <li>if a key is present in both maps, it is passed with both
--   corresponding values to the <tt>combine</tt> function. Depending on
--   the result, the key is either present in the result with specified
--   value, or is left out;</li>
--   <li>a nonempty subtree present only in the first map is passed to
--   <tt>only1</tt> and the output is added to the result;</li>
--   <li>a nonempty subtree present only in the second map is passed to
--   <tt>only2</tt> and the output is added to the result.</li>
--   </ul>
--   
--   The <tt>only1</tt> and <tt>only2</tt> methods <i>must return a map
--   with a subset (possibly empty) of the keys of the given map</i>. The
--   values can be modified arbitrarily. Most common variants of
--   <tt>only1</tt> and <tt>only2</tt> are <a>id</a> and <tt><a>const</a>
--   <a>empty</a></tt>, but for example <tt><a>map</a> f</tt> or
--   <tt><a>filterWithKey</a> f</tt> could be used for any <tt>f</tt>.
mergeWithKey :: (Key -> a -> b -> Maybe c) -> (IntMap a -> IntMap c) -> (IntMap b -> IntMap c) -> IntMap a -> IntMap b -> IntMap c

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   map (++ "x") (fromList [(5,"a"), (3,"b")]) == fromList [(3, "bx"), (5, "ax")]
--   </pre>
map :: (a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map a function over all values in the map.
--   
--   <pre>
--   let f key x = (show key) ++ ":" ++ x
--   mapWithKey f (fromList [(5,"a"), (3,"b")]) == fromList [(3, "3:b"), (5, "5:a")]
--   </pre>
mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. <tt><a>traverseWithKey</a> f s == <a>fromList</a>
--   <a>$</a> <a>traverse</a> ((k, v) -&gt; (,) k <a>$</a> f k v)
--   (<a>toList</a> m)</tt> That is, behaves exactly like a regular
--   <a>traverse</a> except that the traversing function also has access to
--   the key associated with a value.
--   
--   <pre>
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(1, 'a'), (5, 'e')]) == Just (fromList [(1, 'b'), (5, 'f')])
--   traverseWithKey (\k v -&gt; if odd k then Just (succ v) else Nothing) (fromList [(2, 'c')])           == Nothing
--   </pre>
traverseWithKey :: Applicative t => (Key -> a -> t b) -> IntMap a -> t (IntMap b)

-- | &lt;math&gt;. Traverse keys/values and collect the <a>Just</a>
--   results.
traverseMaybeWithKey :: Applicative f => (Key -> a -> f (Maybe b)) -> IntMap a -> f (IntMap b)

-- | &lt;math&gt;. The function <tt><a>mapAccum</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a b = (a ++ b, b ++ "X")
--   mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccum :: (a -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumWithKey</a></tt> threads an
--   accumulating argument through the map in ascending order of keys.
--   
--   <pre>
--   let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
--   mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])
--   </pre>
mapAccumWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. The function <tt><a>mapAccumRWithKey</a></tt> threads an
--   accumulating argument through the map in descending order of keys.
mapAccumRWithKey :: (a -> Key -> b -> (a, c)) -> a -> IntMap b -> (a, IntMap c)

-- | &lt;math&gt;. <tt><a>mapKeys</a> f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the value at the
--   greatest of the original keys is retained.
--   
--   <pre>
--   mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])                        == fromList [(4, "b"), (6, "a")]
--   mapKeys (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "c"
--   mapKeys (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "c"
--   </pre>
mapKeys :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysWith</a> c f s</tt> is the map obtained by
--   applying <tt>f</tt> to each key of <tt>s</tt>.
--   
--   The size of the result may be smaller if <tt>f</tt> maps two or more
--   distinct keys to the same new key. In this case the associated values
--   will be combined using <tt>c</tt>.
--   
--   <pre>
--   mapKeysWith (++) (\ _ -&gt; 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
--   mapKeysWith (++) (\ _ -&gt; 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
--   </pre>
--   
--   Also see the performance note on <a>fromListWith</a>.
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. <tt><a>mapKeysMonotonic</a> f s == <a>mapKeys</a> f
--   s</tt>, but works only when <tt>f</tt> is strictly monotonic. That is,
--   for any values <tt>x</tt> and <tt>y</tt>, if <tt>x</tt> &lt;
--   <tt>y</tt> then <tt>f x</tt> &lt; <tt>f y</tt>. Semi-formally, we
--   have:
--   
--   <pre>
--   and [x &lt; y ==&gt; f x &lt; f y | x &lt;- ls, y &lt;- ls]
--                       ==&gt; mapKeysMonotonic f s == mapKeys f s
--       where ls = keys s
--   </pre>
--   
--   This means that <tt>f</tt> maps distinct original keys to distinct
--   resulting keys. This function has slightly better performance than
--   <a>mapKeys</a>.
--   
--   <b>Warning</b>: This function should be used only if <tt>f</tt> is
--   monotonically strictly increasing. This precondition is not checked.
--   Use <a>mapKeys</a> if the precondition may not hold.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Fold the values in the map using the given
--   right-associative binary operator, such that <tt><a>foldr</a> f z ==
--   <a>foldr</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems map = foldr (:) [] map
--   </pre>
--   
--   <pre>
--   let f a len = len + (length a)
--   foldr f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldr :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the values in the map using the given
--   left-associative binary operator, such that <tt><a>foldl</a> f z ==
--   <a>foldl</a> f z . <a>elems</a></tt>.
--   
--   For example,
--   
--   <pre>
--   elems = reverse . foldl (flip (:)) []
--   </pre>
--   
--   <pre>
--   let f len a = len + (length a)
--   foldl f 0 (fromList [(5,"a"), (3,"bbb")]) == 4
--   </pre>
foldl :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   right-associative binary operator, such that <tt><a>foldrWithKey</a> f
--   z == <a>foldr</a> (<a>uncurry</a> f) z . <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys map = foldrWithKey (\k x ks -&gt; k:ks) [] map
--   </pre>
--   
--   <pre>
--   let f k a result = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldrWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (5:a)(3:b)"
--   </pre>
foldrWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   left-associative binary operator, such that <tt><a>foldlWithKey</a> f
--   z == <a>foldl</a> (\z' (kx, x) -&gt; f z' kx x) z .
--   <a>toAscList</a></tt>.
--   
--   For example,
--   
--   <pre>
--   keys = reverse . foldlWithKey (\ks k x -&gt; k:ks) []
--   </pre>
--   
--   <pre>
--   let f result k a = result ++ "(" ++ (show k) ++ ":" ++ a ++ ")"
--   foldlWithKey f "Map: " (fromList [(5,"a"), (3,"b")]) == "Map: (3:b)(5:a)"
--   </pre>
foldlWithKey :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Fold the keys and values in the map using the given
--   monoid, such that
--   
--   <pre>
--   <a>foldMapWithKey</a> f = <a>fold</a> . <a>mapWithKey</a> f
--   </pre>
--   
--   This can be an asymptotically faster than <a>foldrWithKey</a> or
--   <a>foldlWithKey</a> for some monoids.
foldMapWithKey :: Monoid m => (Key -> a -> m) -> IntMap a -> m

-- | &lt;math&gt;. A strict version of <a>foldr</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldr' :: (a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldl</a>. Each application of
--   the operator is evaluated before using the result in the next
--   application. This function is strict in the starting value.
foldl' :: (a -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. A strict version of <a>foldrWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b

-- | &lt;math&gt;. A strict version of <a>foldlWithKey</a>. Each
--   application of the operator is evaluated before using the result in
--   the next application. This function is strict in the starting value.
foldlWithKey' :: (a -> Key -> b -> a) -> a -> IntMap b -> a

-- | &lt;math&gt;. Return all elements of the map in the ascending order of
--   their keys. Subject to list fusion.
--   
--   <pre>
--   elems (fromList [(5,"a"), (3,"b")]) == ["b","a"]
--   elems empty == []
--   </pre>
elems :: IntMap a -> [a]

-- | &lt;math&gt;. Return all keys of the map in ascending order. Subject
--   to list fusion.
--   
--   <pre>
--   keys (fromList [(5,"a"), (3,"b")]) == [3,5]
--   keys empty == []
--   </pre>
keys :: IntMap a -> [Key]

-- | &lt;math&gt;. An alias for <a>toAscList</a>. Returns all key/value
--   pairs in the map in ascending key order. Subject to list fusion.
--   
--   <pre>
--   assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   assocs empty == []
--   </pre>
assocs :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. The set of all keys of the map.
--   
--   <pre>
--   keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
--   keysSet empty == Data.IntSet.empty
--   </pre>
keysSet :: IntMap a -> IntSet

-- | &lt;math&gt;. Convert the map to a list of key/value pairs. Subject to
--   list fusion.
--   
--   <pre>
--   toList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   toList empty == []
--   </pre>
toList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in ascending order. Subject to list fusion.
--   
--   <pre>
--   toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
--   </pre>
toAscList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Convert the map to a list of key/value pairs where the
--   keys are in descending order. Subject to list fusion.
--   
--   <pre>
--   toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
--   </pre>
toDescList :: IntMap a -> [(Key, a)]

-- | &lt;math&gt;. Filter all values that satisfy some predicate.
--   
--   <pre>
--   filter (&gt; "a") (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   filter (&gt; "x") (fromList [(5,"a"), (3,"b")]) == empty
--   filter (&lt; "a") (fromList [(5,"a"), (3,"b")]) == empty
--   </pre>
filter :: (a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys that satisfy some predicate.
--   
--   <pre>
--   filterKeys p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
--   
--   <pre>
--   filterKeys (&gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterKeys :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Filter all keys/values that satisfy some predicate.
--   
--   <pre>
--   filterWithKey (\k _ -&gt; k &gt; 4) (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. The restriction of a map to the keys in a set.
--   
--   <pre>
--   m `restrictKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`member`</a> s) m
--   </pre>
restrictKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Remove all the keys in a given set from a map.
--   
--   <pre>
--   m `withoutKeys` s = <a>filterWithKey</a> (\k _ -&gt; k <a>`notMember`</a> s) m
--   </pre>
withoutKeys :: IntMap a -> IntSet -> IntMap a

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partition (&gt; "a") (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   partition (&lt; "x") (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partition (&gt; "x") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partition :: (a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Partition the map according to some predicate. The first
--   map contains all elements that satisfy the predicate, the second all
--   elements that fail the predicate. See also <a>split</a>.
--   
--   <pre>
--   partitionWithKey (\ k _ -&gt; k &gt; 3) (fromList [(5,"a"), (3,"b")]) == (singleton 5 "a", singleton 3 "b")
--   partitionWithKey (\ k _ -&gt; k &lt; 7) (fromList [(5,"a"), (3,"b")]) == (fromList [(3, "b"), (5, "a")], empty)
--   partitionWithKey (\ k _ -&gt; k &gt; 7) (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3, "b"), (5, "a")])
--   </pre>
partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Take while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   takeWhileAntitone p = <a>fromDistinctAscList</a> . <a>takeWhile</a> (p . fst) . <a>toList</a>
--   takeWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; p k)
--   </pre>
takeWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Drop while a predicate on the keys holds. The user is
--   responsible for ensuring that for all <tt>Int</tt>s, <tt>j &lt; k
--   ==&gt; p j &gt;= p k</tt>. See note at <a>spanAntitone</a>.
--   
--   <pre>
--   dropWhileAntitone p = <a>fromDistinctAscList</a> . <a>dropWhile</a> (p . fst) . <a>toList</a>
--   dropWhileAntitone p = <a>filterWithKey</a> (\k _ -&gt; not (p k))
--   </pre>
dropWhileAntitone :: (Key -> Bool) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Divide a map at the point where a predicate on the keys
--   stops holding. The user is responsible for ensuring that for all
--   <tt>Int</tt>s, <tt>j &lt; k ==&gt; p j &gt;= p k</tt>.
--   
--   <pre>
--   spanAntitone p xs = (<a>takeWhileAntitone</a> p xs, <a>dropWhileAntitone</a> p xs)
--   spanAntitone p xs = <a>partitionWithKey</a> (\k _ -&gt; p k) xs
--   </pre>
--   
--   Note: if <tt>p</tt> is not actually antitone, then
--   <tt>spanAntitone</tt> will split the map at some <i>unspecified</i>
--   point.
spanAntitone :: (Key -> Bool) -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Map values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f x = if x == "a" then Just "new a" else Nothing
--   mapMaybe f (fromList [(5,"a"), (3,"b")]) == singleton 5 "new a"
--   </pre>
mapMaybe :: (a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map keys/values and collect the <a>Just</a> results.
--   
--   <pre>
--   let f k _ = if k &lt; 5 then Just ("key : " ++ (show k)) else Nothing
--   mapMaybeWithKey f (fromList [(5,"a"), (3,"b")]) == singleton 3 "key : 3"
--   </pre>
mapMaybeWithKey :: (Key -> a -> Maybe b) -> IntMap a -> IntMap b

-- | &lt;math&gt;. Map values and separate the <a>Left</a> and <a>Right</a>
--   results.
--   
--   <pre>
--   let f a = if a &lt; "c" then Left a else Right a
--   mapEither f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(3,"b"), (5,"a")], fromList [(1,"x"), (7,"z")])
--   
--   mapEither (\ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--   </pre>
mapEither :: (a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. Map keys/values and separate the <a>Left</a> and
--   <a>Right</a> results.
--   
--   <pre>
--   let f k a = if k &lt; 5 then Left (k * 2) else Right (a ++ a)
--   mapEitherWithKey f (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (fromList [(1,2), (3,6)], fromList [(5,"aa"), (7,"zz")])
--   
--   mapEitherWithKey (\_ a -&gt; Right a) (fromList [(5,"a"), (3,"b"), (1,"x"), (7,"z")])
--       == (empty, fromList [(1,"x"), (3,"b"), (5,"a"), (7,"z")])
--   </pre>
mapEitherWithKey :: (Key -> a -> Either b c) -> IntMap a -> (IntMap b, IntMap c)

-- | &lt;math&gt;. The expression (<tt><a>split</a> k map</tt>) is a pair
--   <tt>(map1,map2)</tt> where all keys in <tt>map1</tt> are lower than
--   <tt>k</tt> and all keys in <tt>map2</tt> larger than <tt>k</tt>. Any
--   key equal to <tt>k</tt> is found in neither <tt>map1</tt> nor
--   <tt>map2</tt>.
--   
--   <pre>
--   split 2 (fromList [(5,"a"), (3,"b")]) == (empty, fromList [(3,"b"), (5,"a")])
--   split 3 (fromList [(5,"a"), (3,"b")]) == (empty, singleton 5 "a")
--   split 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", singleton 5 "a")
--   split 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", empty)
--   split 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], empty)
--   </pre>
split :: Key -> IntMap a -> (IntMap a, IntMap a)

-- | &lt;math&gt;. Performs a <a>split</a> but also returns whether the
--   pivot key was found in the original map.
--   
--   <pre>
--   splitLookup 2 (fromList [(5,"a"), (3,"b")]) == (empty, Nothing, fromList [(3,"b"), (5,"a")])
--   splitLookup 3 (fromList [(5,"a"), (3,"b")]) == (empty, Just "b", singleton 5 "a")
--   splitLookup 4 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Nothing, singleton 5 "a")
--   splitLookup 5 (fromList [(5,"a"), (3,"b")]) == (singleton 3 "b", Just "a", empty)
--   splitLookup 6 (fromList [(5,"a"), (3,"b")]) == (fromList [(3,"b"), (5,"a")], Nothing, empty)
--   </pre>
splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)

-- | &lt;math&gt;. Decompose a map into pieces based on the structure of
--   the underlying tree. This function is useful for consuming a map in
--   parallel.
--   
--   No guarantee is made as to the sizes of the pieces; an internal, but
--   deterministic process determines this. However, it is guaranteed that
--   the pieces returned will be in ascending order (all elements in the
--   first submap less than all elements in the second, and so on).
--   
--   Examples:
--   
--   <pre>
--   splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
--     [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--   </pre>
--   
--   <pre>
--   splitRoot empty == []
--   </pre>
--   
--   Note that the current implementation does not return more than two
--   submaps, but you should not depend on this behaviour because it can
--   change in the future without notice.
splitRoot :: IntMap a -> [IntMap a]

-- | &lt;math&gt;. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. The expression (<tt><a>isSubmapOfBy</a> f m1 m2</tt>)
--   returns <a>True</a> if all keys in <tt>m1</tt> are in <tt>m2</tt>, and
--   when <tt>f</tt> returns <a>True</a> when applied to their respective
--   values. For example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (&lt;) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   </pre>
isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   Defined as (<tt><a>isProperSubmapOf</a> = <a>isProperSubmapOfBy</a>
--   (==)</tt>).
isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | &lt;math&gt;. Is this a proper submap? (ie. a submap but not equal).
--   The expression (<tt><a>isProperSubmapOfBy</a> f m1 m2</tt>) returns
--   <a>True</a> when <tt>keys m1</tt> and <tt>keys m2</tt> are not equal,
--   all keys in <tt>m1</tt> are in <tt>m2</tt>, and when <tt>f</tt>
--   returns <a>True</a> when applied to their respective values. For
--   example, the following expressions are all <a>True</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (&lt;=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
--   </pre>
--   
--   But the following are all <a>False</a>:
--   
--   <pre>
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
--   isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
--   isProperSubmapOfBy (&lt;)  (fromList [(1,1)])       (fromList [(1,1),(2,2)])
--   </pre>
isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool

-- | &lt;math&gt;. The minimal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMin :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Returns <a>Nothing</a> if
--   the map is empty.
lookupMax :: IntMap a -> Maybe (Key, a)

-- | &lt;math&gt;. The minimal key of the map. Calls <a>error</a> if the
--   map is empty.
findMin :: IntMap a -> (Key, a)

-- | &lt;math&gt;. The maximal key of the map. Calls <a>error</a> if the
--   map is empty.
findMax :: IntMap a -> (Key, a)

-- | &lt;math&gt;. Delete the minimal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMin :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete the maximal key. Returns an empty map if the map
--   is empty.
--   
--   Note that this is a change of behaviour for consistency with
--   <a>Map</a> – versions prior to 0.5 threw an error if the <a>IntMap</a>
--   was already empty.
deleteMax :: IntMap a -> IntMap a

-- | &lt;math&gt;. Delete and find the minimal element. This function
--   throws an error if the map is empty. Use <a>minViewWithKey</a> if the
--   map may be empty.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Delete and find the maximal element. This function
--   throws an error if the map is empty. Use <a>maxViewWithKey</a> if the
--   map may be empty.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMin (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "Xb"), (5, "a")]
--   updateMin (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMin :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMax (\ a -&gt; Just ("X" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "Xa")]
--   updateMax (\ _ -&gt; Nothing)         (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMax :: (a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the minimal key.
--   
--   <pre>
--   updateMinWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"3:b"), (5,"a")]
--   updateMinWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 5 "a"
--   </pre>
updateMinWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Update the value at the maximal key.
--   
--   <pre>
--   updateMaxWithKey (\ k a -&gt; Just ((show k) ++ ":" ++ a)) (fromList [(5,"a"), (3,"b")]) == fromList [(3,"b"), (5,"5:a")]
--   updateMaxWithKey (\ _ _ -&gt; Nothing)                     (fromList [(5,"a"), (3,"b")]) == singleton 3 "b"
--   </pre>
updateMaxWithKey :: (Key -> a -> Maybe a) -> IntMap a -> IntMap a

-- | &lt;math&gt;. Retrieves the minimal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
minView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the maximal key of the map, and the map
--   stripped of that element, or <a>Nothing</a> if passed an empty map.
maxView :: IntMap a -> Maybe (a, IntMap a)

-- | &lt;math&gt;. Retrieves the minimal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")
--   minViewWithKey empty == Nothing
--   </pre>
minViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)

-- | &lt;math&gt;. Retrieves the maximal (key,value) pair of the map, and
--   the map stripped of that element, or <a>Nothing</a> if passed an empty
--   map.
--   
--   <pre>
--   maxViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((5,"a"), singleton 3 "b")
--   maxViewWithKey empty == Nothing
--   </pre>
maxViewWithKey :: IntMap a -> Maybe ((Key, a), IntMap a)


-- | <h1>Finite Int Maps (lazy interface)</h1>
--   
--   This module re-exports the value lazy <a>Data.IntMap.Lazy</a> API.
--   
--   The <tt><a>IntMap</a> v</tt> type represents a finite map (sometimes
--   called a dictionary) from keys of type <tt>Int</tt> to values of type
--   <tt>v</tt>.
--   
--   The functions in <a>Data.IntMap.Strict</a> are careful to force values
--   before installing them in an <a>IntMap</a>. This is usually more
--   efficient in cases where laziness is not essential. The functions in
--   this module do not do so.
--   
--   For a walkthrough of the most commonly used functions see the <a>maps
--   introduction</a>.
--   
--   This module is intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap.Lazy (IntMap)
--   import qualified Data.IntMap.Lazy as IntMap
--   </pre>
--   
--   Note that the implementation is generally <i>left-biased</i>.
--   Functions that take two maps as arguments and combine them, such as
--   <a>union</a> and <a>intersection</a>, prefer the values in the first
--   argument to those in the second.
--   
--   <h2>Implementation</h2>
--   
--   The implementation is based on <i>big-endian patricia trees</i>. This
--   data structure performs especially well on binary operations like
--   <a>union</a> and <a>intersection</a>. Additionally, benchmarks show
--   that it is also (much) faster on insertions and deletions when
--   compared to a generic size-balanced map implementation (see
--   <a>Data.Map</a>).
--   
--   <ul>
--   <li>Chris Okasaki and Andy Gill, "<i>Fast Mergeable Integer Maps</i>",
--   Workshop on ML, September 1998, pages 77-86,
--   <a>https://web.archive.org/web/20150417234429/https://ittc.ku.edu/~andygill/papers/IntMap98.pdf</a>.</li>
--   <li>D.R. Morrison, "<i>PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric</i>", Journal of the ACM, 15(4),
--   October 1968, pages 514-534,
--   <a>https://doi.org/10.1145/321479.321481</a>.</li>
--   </ul>
--   
--   <h2>Performance information</h2>
--   
--   Operation comments contain the operation time complexity in <a>big-O
--   notation</a>, with &lt;math&gt; referring to the number of entries in
--   the map and &lt;math&gt; referring to the number of bits in an
--   <a>Int</a> (32 or 64).
--   
--   Operations like <a>lookup</a>, <a>insert</a>, and <a>delete</a> have a
--   worst-case complexity of &lt;math&gt;. This means that the operation
--   can become linear in the number of elements with a maximum of
--   &lt;math&gt; -- the number of bits in an <a>Int</a> (32 or 64). These
--   peculiar asymptotics are determined by the depth of the Patricia
--   trees:
--   
--   <ul>
--   <li>even for an extremely unbalanced tree, the depth cannot be larger
--   than the number of elements &lt;math&gt;,</li>
--   <li>each level of a Patricia tree determines at least one more bit
--   shared by all subelements, so there could not be more than
--   &lt;math&gt; levels.</li>
--   </ul>
--   
--   If all &lt;math&gt; keys in the tree are between 0 and &lt;math&gt;
--   (or, say, between &lt;math&gt; and &lt;math&gt;), the estimate can be
--   refined to &lt;math&gt;. If the set of keys is sufficiently "dense",
--   this becomes &lt;math&gt; or simply the familiar &lt;math&gt;,
--   matching balanced binary trees.
--   
--   The most performant scenario for <a>IntMap</a> are keys from a
--   contiguous subset, in which case the complexity is proportional to
--   &lt;math&gt;, capped by &lt;math&gt;. The worst scenario are
--   exponentially growing keys &lt;math&gt;, for which complexity grows as
--   fast as &lt;math&gt; but again is capped by &lt;math&gt;.
--   
--   Binary set operations like <a>union</a> and <a>intersection</a> take
--   &lt;math&gt; time, where &lt;math&gt; and &lt;math&gt; are the sizes
--   of the smaller and larger input maps respectively.
module Data.IntMap

module Data.IntMap.Internal.Debug

-- | &lt;math&gt;. Show the tree that implements the map. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | &lt;math&gt;. The expression (<tt><a>showTreeWith</a> hang wide
--   map</tt>) shows the tree that implements the map. If <tt>hang</tt> is
--   <a>True</a>, a <i>hanging</i> tree is shown otherwise a rotated tree
--   is shown. If <tt>wide</tt> is <a>True</a>, an extra wide version is
--   shown.
showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String
