-- 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 basic immutable container types. The declared cost of each
--   operation is either worst-case or amortized, but remains valid even if
--   structures are shared.
@package containers
@version 0.5.6.2


-- | General purpose finite sequences. Apart from being finite and having
--   strict operations, sequences also differ from lists in supporting a
--   wider variety of operations efficiently.
--   
--   An amortized running time is given for each operation, with <i>n</i>
--   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.
--   
--   The implementation uses 2-3 finger trees annotated with sizes, as
--   described in section 4.2 of
--   
--   <ul>
--   <li>Ralf Hinze and Ross Paterson, "Finger trees: a simple
--   general-purpose data structure", <i>Journal of Functional
--   Programming</i> 16:2 (2006) pp 197-217.
--   <a>http://staff.city.ac.uk/~ross/papers/FingerTree.html</a></li>
--   </ul>
--   
--   <i>Note</i>: Many of these operations have the same names as similar
--   operations on lists in the <a>Prelude</a>. The ambiguity may be
--   resolved using either qualification or the <tt>hiding</tt> clause.
module Data.Sequence

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

-- | <i>O(1)</i>. The empty sequence.
empty :: Seq a

-- | <i>O(1)</i>. A singleton sequence.
singleton :: a -> Seq a

-- | <i>O(1)</i>. 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

-- | <i>O(1)</i>. 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

-- | <i>O(log(min(n1,n2)))</i>. Concatenate two sequences.
(><) :: Seq a -> Seq a -> Seq a

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. Convert a given sequence length and a function
--   representing that sequence into a sequence.
fromFunction :: Int -> (Int -> a) -> Seq a

-- | <i>O(n)</i>. 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

-- | <i>O(log n)</i>. <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 <i>O(log n)</i> calls to <a>&lt;*&gt;</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 a sequence counterpart of <a>replicateM</a>.
--   
--   <pre>
--   replicateM n x = sequence (replicate n x)
--   </pre>
replicateM :: Monad m => Int -> m a -> m (Seq a)

-- | <i>O(n)</i>. 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

-- | <i>O(1)</i>. Is this the empty sequence?
null :: Seq a -> Bool

-- | <i>O(1)</i>. 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

-- | <i>O(1)</i>. 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

-- | <i>O(1)</i>. 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

-- | <i>O(n)</i>. 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 <i>i</i>th suffix takes <i>O(log(min(i, n-i)))</i>, but
--   evaluating every suffix in the sequence takes <i>O(n)</i> due to
--   sharing.
tails :: Seq a -> Seq (Seq a)

-- | <i>O(n)</i>. 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 <i>i</i>th prefix takes <i>O(log(min(i, n-i)))</i>, but
--   evaluating every prefix in the sequence takes <i>O(n)</i> due to
--   sharing.
inits :: Seq a -> Seq (Seq a)

-- | <i>O(i)</i> where <i>i</i> 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

-- | <i>O(i)</i> where <i>i</i> 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

-- | <i>O(i)</i> where <i>i</i> 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

-- | <i>O(i)</i> where <i>i</i> 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

-- | <i>O(i)</i> where <i>i</i> 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)

-- | <i>O(i)</i> where <i>i</i> 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)

-- | <i>O(i)</i> where <i>i</i> 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n log n)</i>. <a>sort</a> sorts the specified <a>Seq</a> by the
--   natural ordering of its elements. The sort is stable. If stability is
--   not required, <a>unstableSort</a> can be considerably faster, and in
--   particular uses less memory.
sort :: Ord a => Seq a -> Seq a

-- | <i>O(n log n)</i>. <a>sortBy</a> sorts the specified <a>Seq</a>
--   according to the specified comparator. The sort is stable. If
--   stability is not required, <a>unstableSortBy</a> can be considerably
--   faster, and in particular uses less memory.
sortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | <i>O(n log n)</i>. <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>, and performs extremely well -- frequently twice as fast
--   as <a>sort</a> -- when the sequence is already nearly sorted.
unstableSort :: Ord a => Seq a -> Seq a

-- | <i>O(n log n)</i>. 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>, and
--   performs extremely well -- frequently twice as fast as <a>sortBy</a>
--   -- when the sequence is already nearly sorted.
unstableSortBy :: (a -> a -> Ordering) -> Seq a -> Seq a

-- | <i>O(log(min(i,n-i)))</i>. 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.
index :: Seq a -> Int -> a

-- | <i>O(log(min(i,n-i)))</i>. Update the element at the specified
--   position. If the position is out of range, the original sequence is
--   returned.
adjust :: (a -> a) -> Int -> Seq a -> Seq a

-- | <i>O(log(min(i,n-i)))</i>. 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

-- | <i>O(log(min(i,n-i)))</i>. 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

-- | <i>O(log(min(i,n-i)))</i>. 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

-- | <i>O(log(min(i,n-i)))</i>. 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]

-- | <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. The reverse of a sequence.
reverse :: Seq a -> Seq a

-- | <i>O(min(n1,n2))</i>. <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)

-- | <i>O(min(n1,n2))</i>. <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

-- | <i>O(min(n1,n2,n3))</i>. <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)

-- | <i>O(min(n1,n2,n3))</i>. <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

-- | <i>O(min(n1,n2,n3,n4))</i>. <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)

-- | <i>O(min(n1,n2,n3,n4))</i>. <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
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.ViewR a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.ViewR a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.ViewR a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.ViewR a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.ViewR a)
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.ViewL a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.ViewL a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.ViewL a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.ViewL a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.ViewL a)
instance GHC.Base.Functor Data.Sequence.Seq
instance Data.Foldable.Foldable Data.Sequence.Seq
instance Data.Traversable.Traversable Data.Sequence.Seq
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Seq a)
instance GHC.Base.Monad Data.Sequence.Seq
instance GHC.Base.Applicative Data.Sequence.Seq
instance GHC.Base.MonadPlus Data.Sequence.Seq
instance GHC.Base.Alternative Data.Sequence.Seq
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Sequence.Seq a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Sequence.Seq a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Sequence.Seq a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Sequence.Seq a)
instance GHC.Base.Monoid (Data.Sequence.Seq a)
instance Data.Data.Data a => Data.Data.Data (Data.Sequence.Seq a)
instance Data.Sequence.Sized a => Data.Sequence.Sized (Data.Sequence.FingerTree a)
instance Data.Foldable.Foldable Data.Sequence.FingerTree
instance GHC.Base.Functor Data.Sequence.FingerTree
instance Data.Traversable.Traversable Data.Sequence.FingerTree
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.FingerTree a)
instance Data.Foldable.Foldable Data.Sequence.Digit
instance GHC.Base.Functor Data.Sequence.Digit
instance Data.Traversable.Traversable Data.Sequence.Digit
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Digit a)
instance Data.Sequence.Sized a => Data.Sequence.Sized (Data.Sequence.Digit a)
instance Data.Foldable.Foldable Data.Sequence.Node
instance GHC.Base.Functor Data.Sequence.Node
instance Data.Traversable.Traversable Data.Sequence.Node
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Node a)
instance Data.Sequence.Sized (Data.Sequence.Node a)
instance Data.Sequence.Sized (Data.Sequence.Elem a)
instance GHC.Base.Functor Data.Sequence.Elem
instance Data.Foldable.Foldable Data.Sequence.Elem
instance Data.Traversable.Traversable Data.Sequence.Elem
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Sequence.Elem a)
instance GHC.Base.Functor (Data.Sequence.State s)
instance GHC.Base.Monad (Data.Sequence.State s)
instance GHC.Base.Applicative (Data.Sequence.State s)
instance GHC.Base.Functor Data.Sequence.ViewL
instance Data.Foldable.Foldable Data.Sequence.ViewL
instance Data.Traversable.Traversable Data.Sequence.ViewL
instance GHC.Base.Functor Data.Sequence.ViewR
instance Data.Foldable.Foldable Data.Sequence.ViewR
instance Data.Traversable.Traversable Data.Sequence.ViewR
instance GHC.Exts.IsList (Data.Sequence.Seq a)


-- | Multi-way trees (<i>aka</i> rose trees) and forests.
module Data.Tree

-- | Multi-way trees, also known as <i>rose trees</i>.
data Tree a
Node :: a -> Forest a -> Tree a

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

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

-- | Neat 2-dimensional drawing of a tree.
drawTree :: Tree String -> String

-- | Neat 2-dimensional drawing of a forest.
drawForest :: Forest String -> String

-- | The elements of a tree in pre-order.
flatten :: Tree a -> [a]

-- | Lists of nodes at each level of the tree.
levels :: Tree a -> [[a]]

-- | Build a tree from a seed value
unfoldTree :: (b -> (a, [b])) -> b -> Tree a

-- | Build a forest from a list of seed values
unfoldForest :: (b -> (a, [b])) -> [b] -> Forest 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 (Forest a)

-- | Monadic tree builder, in breadth-first order, 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, 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 (Forest a)
instance Data.Data.Data a => Data.Data.Data (Data.Tree.Tree a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Tree a)
instance GHC.Read.Read a => GHC.Read.Read (Data.Tree.Tree a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Tree a)
instance GHC.Base.Functor Data.Tree.Tree
instance GHC.Base.Applicative Data.Tree.Tree
instance GHC.Base.Monad Data.Tree.Tree
instance Data.Traversable.Traversable Data.Tree.Tree
instance Data.Foldable.Foldable Data.Tree.Tree
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Tree.Tree a)


-- | A version of the graph algorithms described in:
--   
--   <i>Structuring Depth-First Search Algorithms in Haskell</i>, by David
--   King and John Launchbury.
module Data.Graph

-- | The strongly connected components of a directed graph, topologically
--   sorted.
stronglyConnComp :: Ord key => [(node, key, [key])] -> [SCC node]

-- | The strongly connected components of a directed graph, 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.
stronglyConnCompR :: Ord key => [(node, key, [key])] -> [SCC (node, key, [key])]

-- | 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.
CyclicSCC :: [vertex] -> SCC vertex

-- | The vertices of a strongly connected component.
flattenSCC :: SCC vertex -> [vertex]

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

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

-- | Table indexed by a contiguous set of vertices.
type Table a = Array Vertex a

-- | The bounds of a <a>Table</a>.
type Bounds = (Vertex, Vertex)

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

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

-- | 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. The out-list may
--   contain keys that don't correspond to nodes of the graph; they are
--   ignored.
graphFromEdges :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex)

-- | 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]))

-- | Build a graph from a list of edges.
buildG :: Bounds -> [Edge] -> Graph

-- | The graph obtained by reversing all edges.
transposeG :: Graph -> Graph

-- | All vertices of a graph.
vertices :: Graph -> [Vertex]

-- | All edges of a graph.
edges :: Graph -> [Edge]

-- | A table of the count of edges from each node.
outdegree :: Graph -> Table Int

-- | A table of the count of edges into each node.
indegree :: Graph -> Table Int

-- | 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] -> Forest Vertex

-- | 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 -> Forest Vertex

-- | 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.
topSort :: Graph -> [Vertex]

-- | The connected components of a graph. Two vertices are connected if
--   there is a path between them, traversing edges in either direction.
components :: Graph -> Forest Vertex

-- | The strongly connected components of a graph.
scc :: Graph -> Forest Vertex

-- | The biconnected components of a graph. An undirected graph is
--   biconnected if the deletion of any vertex leaves it connected.
bcc :: Graph -> Forest [Vertex]

-- | A list of vertices reachable from a given vertex.
reachable :: Graph -> Vertex -> [Vertex]

-- | Is the second vertex reachable from the first?
path :: Graph -> Vertex -> Vertex -> Bool
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Graph.SCC a)
instance GHC.Base.Functor Data.Graph.SCC
instance GHC.Base.Monad (Data.Graph.SetM s)
instance GHC.Base.Functor (Data.Graph.SetM s)
instance GHC.Base.Applicative (Data.Graph.SetM s)


-- | An efficient implementation of ordered maps from keys to values
--   (dictionaries).
--   
--   API of this module is strict in the keys, but lazy in the values. If
--   you need value-strict maps, use <a>Data.Map.Strict</a> instead. The
--   <a>Map</a> type itself is shared between the lazy and strict modules,
--   meaning that the same <a>Map</a> value can be passed to functions in
--   both modules (although that is rarely needed).
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import qualified Data.Map.Lazy as Map
--   </pre>
--   
--   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>http://www.swiss.ai.mit.edu/~adams/BB/</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.</li>
--   </ul>
--   
--   Note that the implementation is <i>left-biased</i> -- the elements of
--   a first argument are always preferred to the second, for example in
--   <a>union</a> or <a>insert</a>.
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation (<a>http://en.wikipedia.org/wiki/Big_O_notation</a>).
module Data.Map.Lazy

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

-- | <i>O(log n)</i>. 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

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

-- | <i>O(1)</i>. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. Lookup 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | <i>O(1)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. 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>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. 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>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
--   function returns 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)

-- | <i>O(log n)</i>. 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>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(n+m)</i>. 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>). The
--   implementation uses the efficient <i>hedge-union</i> algorithm.
--   
--   <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

-- | <i>O(n+m)</i>. Union with a combining function. The implementation
--   uses the efficient <i>hedge-union</i> algorithm.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(n+m)</i>. Union with a combining function. The implementation
--   uses the efficient <i>hedge-union</i> algorithm.
--   
--   <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>
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 :: Ord k => [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 :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(n+m)</i>. Difference of two maps. Return elements of the first
--   map not existing in the second map. The implementation uses an
--   efficient <i>hedge</i> algorithm comparable with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>. The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>. The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>). The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. Intersection with a combining function. The
--   implementation uses an efficient <i>hedge</i> algorithm comparable
--   with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. Intersection with a combining function. The
--   implementation uses an efficient <i>hedge</i> algorithm comparable
--   with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. A high-performance universal combining function. This
--   function is used to define <a>unionWith</a>, <a>unionWithKey</a>,
--   <a>differenceWith</a>, <a>differenceWithKey</a>,
--   <a>intersectionWith</a>, <a>intersectionWithKey</a> and can be used to
--   define other custom combine functions.
--   
--   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 <tt>IntMap</tt>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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. <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 => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> 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)

-- | <i>O(n*log n)</i>. <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 :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <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>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <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>. <i>The precondition is
--   not checked.</i> 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>.
--   
--   <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*log n)</i>. 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 of the list are ordered, linear-time implementation is
--   used, with the performance equal to <a>fromDistinctAscList</a>.
--   
--   <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

-- | <i>O(n*log n)</i>. 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,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
--   fromListWith (++) [] == empty
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ a1 ++ a2
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
--   fromListWithKey f [] == empty
--   </pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
--   precondition (input list is ascending) is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
--   combining function for equal keys. <i>The precondition (input list is
--   ascending) is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
--   combining function for equal keys. <i>The precondition (input list is
--   ascending) is not checked.</i>
--   
--   <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>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
--   in linear time. <i>The precondition is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. 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]

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>m1</tt> and <tt>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

-- | <i>O(log n)</i>. Lookup 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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


-- | An efficient implementation of ordered maps from keys to values
--   (dictionaries).
--   
--   API of this module is strict in both the keys and the values. If you
--   need value-lazy maps, use <a>Data.Map.Lazy</a> instead. 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
--   (although that is rarely needed).
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import qualified Data.Map.Strict as Map
--   </pre>
--   
--   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>http://www.swiss.ai.mit.edu/~adams/BB/</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.</li>
--   </ul>
--   
--   Note that the implementation is <i>left-biased</i> -- the elements of
--   a first argument are always preferred to the second, for example in
--   <a>union</a> or <a>insert</a>.
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation (<a>http://en.wikipedia.org/wiki/Big_O_notation</a>).
--   
--   Be aware that the <a>Functor</a>, <a>Traversable</a> and <tt>Data</tt>
--   instances are the same as for the <a>Data.Map.Lazy</a> module, so if
--   they are used on strict maps, the resulting maps will be lazy.
module Data.Map.Strict

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

-- | <i>O(log n)</i>. 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

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

-- | <i>O(1)</i>. Is the map empty?
--   
--   <pre>
--   Data.Map.null (empty)           == True
--   Data.Map.null (singleton 1 'a') == False
--   </pre>
null :: Map k a -> Bool

-- | <i>O(1)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. Lookup 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: Map k a

-- | <i>O(1)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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>
insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. 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>
insertWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>O(log n)</i>. 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>
insertLookupWithKey :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. Lookup and update. See also <a>updateWithKey</a>. The
--   function returns 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)

-- | <i>O(log n)</i>. 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>
alter :: Ord k => (Maybe a -> Maybe a) -> k -> Map k a -> Map k a

-- | <i>O(n+m)</i>. 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>). The
--   implementation uses the efficient <i>hedge-union</i> algorithm.
--   
--   <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

-- | <i>O(n+m)</i>. Union with a combining function. The implementation
--   uses the efficient <i>hedge-union</i> algorithm.
--   
--   <pre>
--   unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
--   </pre>
unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a

-- | <i>O(n+m)</i>. Union with a combining function. The implementation
--   uses the efficient <i>hedge-union</i> algorithm.
--   
--   <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>
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 :: Ord k => [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 :: Ord k => (a -> a -> a) -> [Map k a] -> Map k a

-- | <i>O(n+m)</i>. Difference of two maps. Return elements of the first
--   map not existing in the second map. The implementation uses an
--   efficient <i>hedge</i> algorithm comparable with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>. The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>. The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. 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>). The implementation
--   uses an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. Intersection with a combining function. The
--   implementation uses an efficient <i>hedge</i> algorithm comparable
--   with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. Intersection with a combining function. The
--   implementation uses an efficient <i>hedge</i> algorithm comparable
--   with <i>hedge-union</i>.
--   
--   <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

-- | <i>O(n+m)</i>. A high-performance universal combining function. This
--   function is used to define <a>unionWith</a>, <a>unionWithKey</a>,
--   <a>differenceWith</a>, <a>differenceWithKey</a>,
--   <a>intersectionWith</a>, <a>intersectionWithKey</a> and can be used to
--   define other custom combine functions.
--   
--   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 <tt>IntMap</tt>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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. <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 => (k -> a -> t b) -> Map k a -> t (Map k b)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. The function <tt>mapAccumR</tt> 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)

-- | <i>O(n*log n)</i>. <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 :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n*log n)</i>. <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>
mapKeysWith :: Ord k2 => (a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a

-- | <i>O(n)</i>. <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>. <i>The precondition is
--   not checked.</i> 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>.
--   
--   <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*log n)</i>. 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 of the list are ordered, linear-time implementation is
--   used, with the performance equal to <a>fromDistinctAscList</a>.
--   
--   <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

-- | <i>O(n*log n)</i>. 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,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
--   fromListWith (++) [] == empty
--   </pre>
fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n*log n)</i>. Build a map from a list of key/value pairs with a
--   combining function. See also <a>fromAscListWithKey</a>.
--   
--   <pre>
--   let f k a1 a2 = (show k) ++ a1 ++ a2
--   fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "3ab"), (5, "5a5ba")]
--   fromListWithKey f [] == empty
--   </pre>
fromListWithKey :: Ord k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. Build a map from an ascending list in linear time. <i>The
--   precondition (input list is ascending) is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
--   combining function for equal keys. <i>The precondition (input list is
--   ascending) is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. Build a map from an ascending list in linear time with a
--   combining function for equal keys. <i>The precondition (input list is
--   ascending) is not checked.</i>
--   
--   <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>
fromAscListWithKey :: Eq k => (k -> a -> a -> a) -> [(k, a)] -> Map k a

-- | <i>O(n)</i>. Build a map from an ascending list of distinct elements
--   in linear time. <i>The precondition is not checked.</i>
--   
--   <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. 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]

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>
isSubmapOfBy :: Ord k => (a -> b -> Bool) -> Map k a -> Map k b -> Bool

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>m1</tt> and <tt>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

-- | <i>O(log n)</i>. Lookup 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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


-- | <i>Note:</i> You should use <a>Data.Map.Strict</a> instead of this
--   module if:
--   
--   <ul>
--   <li>You will eventually need all the values stored.</li>
--   <li>The stored values don't represent large virtual data structures to
--   be lazily computed.</li>
--   </ul>
--   
--   An efficient implementation of ordered maps from keys to values
--   (dictionaries).
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import qualified Data.Map as Map
--   </pre>
--   
--   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>http://www.swiss.ai.mit.edu/~adams/BB/</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.</li>
--   </ul>
--   
--   Note that the implementation is <i>left-biased</i> -- the elements of
--   a first argument are always preferred to the second, for example in
--   <a>union</a> or <a>insert</a>.
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation (<a>http://en.wikipedia.org/wiki/Big_O_notation</a>).
module Data.Map

-- | <i>Deprecated.</i> As of version 0.5, replaced by <a>insertWith</a>.
--   
--   <i>O(log n)</i>. Same as <a>insertWith</a>, but the value being
--   inserted to the map is evaluated to WHNF beforehand.
--   
--   For example, to update a counter:
--   
--   <pre>
--   insertWith' (+) k 1 m
--   </pre>
insertWith' :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>Deprecated.</i> As of version 0.5, replaced by
--   <a>insertWithKey</a>.
--   
--   <i>O(log n)</i>. Same as <a>insertWithKey</a>, but the value being
--   inserted to the map is evaluated to WHNF beforehand.
insertWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> Map k a

-- | <i>Deprecated.</i> As of version 0.5, replaced by
--   <a>insertLookupWithKey</a>.
--   
--   <i>O(log n)</i>. Same as <a>insertLookupWithKey</a>, but the value
--   being inserted to the map is evaluated to WHNF beforehand.
insertLookupWithKey' :: Ord k => (k -> a -> a -> a) -> k -> a -> Map k a -> (Maybe a, Map k a)

-- | <i>Deprecated.</i> As of version 0.5, replaced by <a>foldr</a>.
--   
--   <i>O(n)</i>. Fold the values in the map using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldr</a> and is present for compatibility only.
fold :: (a -> b -> b) -> b -> Map k a -> b

-- | <i>Deprecated.</i> As of version 0.4, replaced by <a>foldrWithKey</a>.
--   
--   <i>O(n)</i>. Fold the keys and values in the map using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldrWithKey</a> and is present for compatibility only.
foldWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b


-- | An efficient implementation of sets.
--   
--   These modules are 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>
--   
--   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>http://www.swiss.ai.mit.edu/~adams/BB/</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.</li>
--   </ul>
--   
--   Note that the implementation is <i>left-biased</i> -- the elements of
--   a first argument are always preferred to the second, for example in
--   <a>union</a> or <a>insert</a>. Of course, left-biasing can only be
--   observed when equality is an equivalence relation instead of
--   structural equality.
module Data.Set

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

-- | <i>O(n+m)</i>. See <a>difference</a>.
(\\) :: Ord a => Set a -> Set a -> Set a

-- | <i>O(1)</i>. Is this the empty set?
null :: Set a -> Bool

-- | <i>O(1)</i>. The number of elements in the set.
size :: Set a -> Int

-- | <i>O(log n)</i>. Is the element in the set?
member :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. Is the element not in the set?
notMember :: Ord a => a -> Set a -> Bool

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
--   tells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: Ord a => Set a -> Set a -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: Set a

-- | <i>O(1)</i>. Create a singleton set.
singleton :: a -> Set a

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. Delete an element from a set.
delete :: Ord a => a -> Set a -> Set a

-- | <i>O(n+m)</i>. The union of two sets, preferring the first set when
--   equal elements are encountered. The implementation uses the efficient
--   <i>hedge-union</i> algorithm.
union :: Ord a => Set a -> Set a -> Set a

-- | The union of a list of sets: (<tt><a>unions</a> == <a>foldl</a>
--   <a>union</a> <a>empty</a></tt>).
unions :: Ord a => [Set a] -> Set a

-- | <i>O(n+m)</i>. Difference of two sets. The implementation uses an
--   efficient <i>hedge</i> algorithm comparable with <i>hedge-union</i>.
difference :: Ord a => Set a -> Set a -> Set a

-- | <i>O(n+m)</i>. The intersection of two sets. The implementation uses
--   an efficient <i>hedge</i> algorithm comparable with
--   <i>hedge-union</i>. 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

-- | <i>O(n)</i>. Filter all elements that satisfy the predicate.
filter :: (a -> Bool) -> Set a -> Set a

-- | <i>O(n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. 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]

-- | <i>O(log n)</i>. Lookup 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(n*log n)</i>. <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 :: Ord b => (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. The
--   
--   <tt><a>mapMonotonic</a> f s == <a>map</a> f s</tt>, but works only
--   when <tt>f</tt> is monotonic. <i>The precondition is not checked.</i>
--   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>
mapMonotonic :: (a -> b) -> Set a -> Set b

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. Fold the elements in the set using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldr</a> and is present for compatibility only.
--   
--   <i>Please note that fold will be deprecated in the future and
--   removed.</i>
fold :: (a -> b -> b) -> b -> Set a -> b

-- | <i>O(log n)</i>. The minimal element of a set.
findMin :: Set a -> a

-- | <i>O(log n)</i>. The maximal element of a set.
findMax :: Set a -> a

-- | <i>O(log n)</i>. Delete the minimal element. Returns an empty set if
--   the set is empty.
deleteMin :: Set a -> Set a

-- | <i>O(log n)</i>. Delete the maximal element. Returns an empty set if
--   the set is empty.
deleteMax :: Set a -> Set a

-- | <i>O(log n)</i>. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: Set a -> (a, Set a)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: Set a -> [a]

-- | <i>O(n*log n)</i>. Create a set from a list of elements.
--   
--   If the elemens are ordered, linear-time implementation is used, with
--   the performance equal to <a>fromDistinctAscList</a>.
fromList :: Ord a => [a] -> Set a

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
--   to list fusion.
toAscList :: Set a -> [a]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
--   to list fusion.
toDescList :: Set a -> [a]

-- | <i>O(n)</i>. Build a set from an ascending list in linear time. <i>The
--   precondition (input list is ascending) is not checked.</i>
fromAscList :: Eq a => [a] -> Set a

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements
--   in linear time. <i>The precondition (input list is strictly ascending)
--   is not checked.</i>
fromDistinctAscList :: [a] -> Set a

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => Set a -> String

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. Test if the internal set structure is valid.
valid :: Ord a => Set a -> Bool


-- | An efficient implementation of integer sets.
--   
--   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>
--   
--   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>. However, my 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>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
--   <li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric/", Journal of the ACM, 15(4),
--   October 1968, pages 514-534.</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 reduce 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.
--   
--   Many operations have a worst-case complexity of <i>O(min(n,W))</i>.
--   This means that the operation can become linear in the number of
--   elements with a maximum of <i>W</i> -- the number of bits in an
--   <a>Int</a> (32 or 64).
module Data.IntSet

-- | A set of integers.
data IntSet
type Key = Int

-- | <i>O(n+m)</i>. See <a>difference</a>.
(\\) :: IntSet -> IntSet -> IntSet

-- | <i>O(1)</i>. Is the set empty?
null :: IntSet -> Bool

-- | <i>O(n)</i>. Cardinality of the set.
size :: IntSet -> Int

-- | <i>O(min(n,W))</i>. Is the value a member of the set?
member :: Key -> IntSet -> Bool

-- | <i>O(min(n,W))</i>. Is the element not in the set?
notMember :: Key -> IntSet -> Bool

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(n+m)</i>. Is this a subset? <tt>(s1 <a>isSubsetOf</a> s2)</tt>
--   tells whether <tt>s1</tt> is a subset of <tt>s2</tt>.
isSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(n+m)</i>. Is this a proper subset? (ie. a subset but not equal).
isProperSubsetOf :: IntSet -> IntSet -> Bool

-- | <i>O(1)</i>. The empty set.
empty :: IntSet

-- | <i>O(1)</i>. A set of one element.
singleton :: Key -> IntSet

-- | <i>O(min(n,W))</i>. Add a value to the set. There is no left- or right
--   bias for IntSets.
insert :: Key -> IntSet -> IntSet

-- | <i>O(min(n,W))</i>. Delete a value in the set. Returns the original
--   set when the value was not present.
delete :: Key -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The union of two sets.
union :: IntSet -> IntSet -> IntSet

-- | The union of a list of sets.
unions :: [IntSet] -> IntSet

-- | <i>O(n+m)</i>. Difference between two sets.
difference :: IntSet -> IntSet -> IntSet

-- | <i>O(n+m)</i>. The intersection of two sets.
intersection :: IntSet -> IntSet -> IntSet

-- | <i>O(n)</i>. Filter all elements that satisfy some predicate.
filter :: (Key -> Bool) -> IntSet -> IntSet

-- | <i>O(n)</i>. partition the set according to some predicate.
partition :: (Key -> Bool) -> IntSet -> (IntSet, IntSet)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. Performs a <a>split</a> but also returns whether
--   the pivot element was found in the original set.
splitMember :: Key -> IntSet -> (IntSet, Bool, IntSet)

-- | <i>O(1)</i>. 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]

-- | <i>O(n*min(n,W))</i>. <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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. Fold the elements in the set using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldr</a> and is present for compatibility only.
--   
--   <i>Please note that fold will be deprecated in the future and
--   removed.</i>
fold :: (Key -> b -> b) -> b -> IntSet -> b

-- | <i>O(min(n,W))</i>. The minimal element of the set.
findMin :: IntSet -> Key

-- | <i>O(min(n,W))</i>. The maximal element of a set.
findMax :: IntSet -> Key

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Delete and find the minimal element.
--   
--   <pre>
--   deleteFindMin set = (findMin set, deleteMin set)
--   </pre>
deleteFindMin :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element.
--   
--   <pre>
--   deleteFindMax set = (findMax set, deleteMax set)
--   </pre>
deleteFindMax :: IntSet -> (Key, IntSet)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(n)</i>. An alias of <a>toAscList</a>. The elements of a set in
--   ascending order. Subject to list fusion.
elems :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a list of elements. Subject to list
--   fusion.
toList :: IntSet -> [Key]

-- | <i>O(n*min(n,W))</i>. Create a set from a list of integers.
fromList :: [Key] -> IntSet

-- | <i>O(n)</i>. Convert the set to an ascending list of elements. Subject
--   to list fusion.
toAscList :: IntSet -> [Key]

-- | <i>O(n)</i>. Convert the set to a descending list of elements. Subject
--   to list fusion.
toDescList :: IntSet -> [Key]

-- | <i>O(n)</i>. Build a set from an ascending list of elements. <i>The
--   precondition (input list is ascending) is not checked.</i>
fromAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Build a set from an ascending list of distinct elements.
--   <i>The precondition (input list is strictly ascending) is not
--   checked.</i>
fromDistinctAscList :: [Key] -> IntSet

-- | <i>O(n)</i>. Show the tree that implements the set. The tree is shown
--   in a compressed, hanging format.
showTree :: IntSet -> String

-- | <i>O(n)</i>. 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


-- | An efficient implementation of maps from integer keys to values
--   (dictionaries).
--   
--   API of this module is strict in both the keys and the values. If you
--   need value-lazy maps, use <a>Data.IntMap.Lazy</a> instead. The
--   <a>IntMap</a> type itself is shared between the lazy and strict
--   modules, meaning that the same <a>IntMap</a> value can be passed to
--   functions in both modules (although that is rarely needed).
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap.Strict (IntMap)
--   import qualified Data.IntMap.Strict as IntMap
--   </pre>
--   
--   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>. However, my 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>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
--   <li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric/", Journal of the ACM, 15(4),
--   October 1968, pages 514-534.</li>
--   </ul>
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
--   operations have a worst-case complexity of <i>O(min(n,W))</i>. This
--   means that the operation can become linear in the number of elements
--   with a maximum of <i>W</i> -- the number of bits in an <a>Int</a> (32
--   or 64).
--   
--   Be aware that the <a>Functor</a>, <a>Traversable</a> and <tt>Data</tt>
--   instances are the same as for the <a>Data.IntMap.Lazy</a> module, so
--   if they are used on strict maps, the resulting maps will be lazy.
module Data.IntMap.Strict

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | <i>O(min(n,W))</i>. 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

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(1)</i>. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | <i>O(n)</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Lookup the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | <i>O(1)</i>. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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>
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. 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>x</tt> but
--   strict in the result of <tt>f</tt>.
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. 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>
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Lookup 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)

-- | <i>O(log n)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. 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>
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 :: [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 :: (a -> a -> a) -> [IntMap a] -> IntMap a

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>).
--   
--   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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. <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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. The function <tt><tt>mapAccumR</tt></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)

-- | <i>O(n*min(n,W))</i>. <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

-- | <i>O(n*log n)</i>. <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>
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <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>. <i>The
--   precondition is not checked.</i> 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>.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*min(n,W))</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*min(n,W))</i>. 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

-- | <i>O(n*min(n,W))</i>. Create 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,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
--   fromListWith (++) [] == empty
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. Build a map from a list of key/value pairs with
--   a combining function. See also fromAscListWithKey'.
--   
--   <pre>
--   fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]
--   fromListWith (++) [] == empty
--   </pre>
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order.
--   
--   <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

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order, with a combining function on equal keys.
--   <i>The precondition (input list is ascending) is not checked.</i>
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order, with a combining function on equal keys.
--   <i>The precondition (input list is ascending) is not checked.</i>
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order and all distinct. <i>The precondition (input
--   list is strictly ascending) is not checked.</i>
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(1)</i>. 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]

-- | <i>O(n+m)</i>. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>m1</tt> and <tt>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

-- | <i>O(min(n,W))</i>. The minimal key of the map.
findMin :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map.
findMax :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Delete and find the minimal element.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(log n)</i>. 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

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. 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


-- | An efficient implementation of maps from integer keys to values
--   (dictionaries).
--   
--   API of this module is strict in the keys, but lazy in the values. If
--   you need value-strict maps, use <a>Data.IntMap.Strict</a> instead. The
--   <a>IntMap</a> type itself is shared between the lazy and strict
--   modules, meaning that the same <a>IntMap</a> value can be passed to
--   functions in both modules (although that is rarely needed).
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap.Lazy (IntMap)
--   import qualified Data.IntMap.Lazy as IntMap
--   </pre>
--   
--   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>. However, my 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>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
--   <li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric/", Journal of the ACM, 15(4),
--   October 1968, pages 514-534.</li>
--   </ul>
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
--   operations have a worst-case complexity of <i>O(min(n,W))</i>. This
--   means that the operation can become linear in the number of elements
--   with a maximum of <i>W</i> -- the number of bits in an <a>Int</a> (32
--   or 64).
module Data.IntMap.Lazy

-- | A map of integers to values <tt>a</tt>.
data IntMap a
type Key = Int

-- | <i>O(min(n,W))</i>. 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

-- | Same as <a>difference</a>.
(\\) :: IntMap a -> IntMap b -> IntMap a

-- | <i>O(1)</i>. Is the map empty?
--   
--   <pre>
--   Data.IntMap.null (empty)           == True
--   Data.IntMap.null (singleton 1 'a') == False
--   </pre>
null :: IntMap a -> Bool

-- | <i>O(n)</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Lookup the value at a key in the map. See also
--   <a>lookup</a>.
lookup :: Key -> IntMap a -> Maybe a

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(log n)</i>. 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)

-- | <i>O(1)</i>. The empty map.
--   
--   <pre>
--   empty      == fromList []
--   size empty == 0
--   </pre>
empty :: IntMap a

-- | <i>O(1)</i>. A map of one element.
--   
--   <pre>
--   singleton 1 'a'        == fromList [(1, 'a')]
--   size (singleton 1 'a') == 1
--   </pre>
singleton :: Key -> a -> IntMap a

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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>
insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. 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>
insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>O(min(n,W))</i>. 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>
insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Lookup 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)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>
unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a

-- | <i>O(n+m)</i>. 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>
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 :: [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 :: (a -> a -> a) -> [IntMap a] -> IntMap a

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>).
--   
--   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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. <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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. The function <tt><tt>mapAccumR</tt></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)

-- | <i>O(n*min(n,W))</i>. <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

-- | <i>O(n*min(n,W))</i>. <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>
mapKeysWith :: (a -> a -> a) -> (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n*min(n,W))</i>. <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>. <i>The
--   precondition is not checked.</i> 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>.
--   
--   <pre>
--   mapKeysMonotonic (\ k -&gt; k * 2) (fromList [(5,"a"), (3,"b")]) == fromList [(6, "b"), (10, "a")]
--   </pre>
mapKeysMonotonic :: (Key -> Key) -> IntMap a -> IntMap a

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*min(n,W))</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)]

-- | <i>O(n*min(n,W))</i>. 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

-- | <i>O(n*min(n,W))</i>. Create 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,"b"), (3,"a"), (5,"c")] == fromList [(3, "ab"), (5, "cba")]
--   fromListWith (++) [] == empty
--   </pre>
fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n*min(n,W))</i>. 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>
fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. 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)]

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order.
--   
--   <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

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order, with a combining function on equal keys.
--   <i>The precondition (input list is ascending) is not checked.</i>
--   
--   <pre>
--   fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
--   </pre>
fromAscListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order, with a combining function on equal keys.
--   <i>The precondition (input list is ascending) is not checked.</i>
--   
--   <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>
fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. Build a map from a list of key/value pairs where the keys
--   are in ascending order and all distinct. <i>The precondition (input
--   list is strictly ascending) is not checked.</i>
--   
--   <pre>
--   fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")]
--   </pre>
fromDistinctAscList :: [(Key, a)] -> IntMap a

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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

-- | <i>O(n)</i>. 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)

-- | <i>O(n)</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(1)</i>. 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]

-- | <i>O(n+m)</i>. Is this a submap? Defined as (<tt><a>isSubmapOf</a> =
--   <a>isSubmapOfBy</a> (==)</tt>).
isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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

-- | <i>O(n+m)</i>. 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>m1</tt> and <tt>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

-- | <i>O(min(n,W))</i>. The minimal key of the map.
findMin :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. The maximal key of the map.
findMax :: IntMap a -> (Key, a)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. Delete and find the minimal element.
deleteFindMin :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. Delete and find the maximal element.
deleteFindMax :: IntMap a -> ((Key, a), IntMap a)

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(min(n,W))</i>. 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)

-- | <i>O(n)</i>. Show the tree that implements the map. The tree is shown
--   in a compressed, hanging format.
showTree :: Show a => IntMap a -> String

-- | <i>O(n)</i>. 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


-- | An efficient implementation of maps from integer keys to values
--   (dictionaries).
--   
--   This module re-exports the value lazy <a>Data.IntMap.Lazy</a> API,
--   plus several deprecated value strict functions. Please note that these
--   functions have different strictness properties than those in
--   <a>Data.IntMap.Strict</a>: they only evaluate the result of the
--   combining function. For example, the default value to
--   <a>insertWith'</a> is only evaluated if the combining function is
--   called and uses it.
--   
--   These modules are intended to be imported qualified, to avoid name
--   clashes with Prelude functions, e.g.
--   
--   <pre>
--   import Data.IntMap (IntMap)
--   import qualified Data.IntMap as IntMap
--   </pre>
--   
--   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>. However, my 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>http://citeseer.ist.psu.edu/okasaki98fast.html</a></li>
--   <li>D.R. Morrison, "/PATRICIA -- Practical Algorithm To Retrieve
--   Information Coded In Alphanumeric/", Journal of the ACM, 15(4),
--   October 1968, pages 514-534.</li>
--   </ul>
--   
--   Operation comments contain the operation time complexity in the Big-O
--   notation <a>http://en.wikipedia.org/wiki/Big_O_notation</a>. Many
--   operations have a worst-case complexity of <i>O(min(n,W))</i>. This
--   means that the operation can become linear in the number of elements
--   with a maximum of <i>W</i> -- the number of bits in an <tt>Int</tt>
--   (32 or 64).
module Data.IntMap

-- | <i>Deprecated.</i> As of version 0.5, replaced by <a>insertWith</a>.
--   
--   <i>O(log n)</i>. Same as <a>insertWith</a>, but the result of the
--   combining function is evaluated to WHNF before inserted to the map.
insertWith' :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>Deprecated.</i> As of version 0.5, replaced by
--   <a>insertWithKey</a>.
--   
--   <i>O(log n)</i>. Same as <a>insertWithKey</a>, but the result of the
--   combining function is evaluated to WHNF before inserted to the map.
insertWithKey' :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a

-- | <i>Deprecated.</i> As of version 0.5, replaced by <a>foldr</a>.
--   
--   <i>O(n)</i>. Fold the values in the map using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldr</a> and is present for compatibility only.
fold :: (a -> b -> b) -> b -> IntMap a -> b

-- | <i>Deprecated.</i> As of version 0.5, replaced by <a>foldrWithKey</a>.
--   
--   <i>O(n)</i>. Fold the keys and values in the map using the given
--   right-associative binary operator. This function is an equivalent of
--   <a>foldrWithKey</a> and is present for compatibility only.
foldWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b
