splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)
splitLookup k m
    | k < 0 = let (glb, eq, WordMap lub) = W.splitLookup (i2w k) (WordMap neg)
              in (IntMap glb, eq, IntMap (WordMap (W.binL nonneg (W.l2rMap lub))))
    | otherwise = let (WordMap glb, eq, lub) = W.splitLookup (i2w k) (WordMap nonneg)
                  in (IntMap (WordMap (W.binL glb (W.l2rMap neg))), eq, IntMap lub)
  where
    (neg, nonneg) = split0 m

-- | /O(1)/.  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:
--
-- > splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
-- >   [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--
-- > splitRoot empty == []
--
--  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.

splitLookup :: Key -> IntMap a -> (IntMap a, Maybe a, IntMap a)
splitLookup k m
    | k < 0 = let (glb, eq, WordMap lub) = W.splitLookup (i2w k) (WordMap neg)
              in (IntMap glb, eq, IntMap (WordMap (W.binL nonneg (W.l2rMap lub))))
    | otherwise = let (WordMap glb, eq, lub) = W.splitLookup (i2w k) (WordMap nonneg)
                  in (IntMap (WordMap (W.binL glb (W.l2rMap neg))), eq, IntMap lub)
  where
    (neg, nonneg) = split0 m

-- | /O(1)/.  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:
--
-- > splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
-- >   [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--
-- > splitRoot empty == []
--
--  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.

splitLookup k m
    | k < 0 = let (glb, eq, WordMap lub) = W.splitLookup (i2w k) (WordMap neg)
              in (IntMap glb, eq, IntMap (WordMap (W.binL nonneg (W.l2rMap lub))))
    | otherwise = let (WordMap glb, eq, lub) = W.splitLookup (i2w k) (WordMap nonneg)
                  in (IntMap (WordMap (W.binL glb (W.l2rMap neg))), eq, IntMap lub)
  where
    (neg, nonneg) = split0 m

-- | /O(1)/.  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:
--
-- > splitRoot (fromList (zip [1..6::Int] ['a'..])) ==
-- >   [fromList [(1,'a'),(2,'b'),(3,'c')],fromList [(4,'d'),(5,'e'),(6,'f')]]
--
-- > splitRoot empty == []
--
--  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.
