foldrWithKey' :: (Key -> a -> b -> b) -> b -> IntMap a -> b
foldrWithKey' f z = start
  where
    start (IntMap (WordMap Empty)) = z
    start (IntMap (WordMap (NonEmpty min minV Tip))) = f' min minV $! z
    start (IntMap (WordMap (NonEmpty min minV (Bin max maxV l r))))
        | w2i (xor min max) < 0 = goR r $! f' max maxV $! f' min minV $! goL l $! z
        | otherwise = f' min minV $! goL l $! goR r $! f' max maxV $! z
    
    goL Tip acc = acc
    goL (Bin max maxV l r) acc = goL l $! goR r $! f' max maxV $! acc
    
    goR Tip acc = acc
    goR (Bin min minV l r) acc = f' min minV $! goL l $! goR r $! acc
    
    f' k a b = f (w2i k) a b

-- | /O(n)/. A strict version of 'foldlWithKey'. 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
foldrWithKey' f z = start
  where
    start (IntMap (WordMap Empty)) = z
    start (IntMap (WordMap (NonEmpty min minV Tip))) = f' min minV $! z
    start (IntMap (WordMap (NonEmpty min minV (Bin max maxV l r))))
        | w2i (xor min max) < 0 = goR r $! f' max maxV $! f' min minV $! goL l $! z
        | otherwise = f' min minV $! goL l $! goR r $! f' max maxV $! z
    
    goL Tip acc = acc
    goL (Bin max maxV l r) acc = goL l $! goR r $! f' max maxV $! acc
    
    goR Tip acc = acc
    goR (Bin min minV l r) acc = f' min minV $! goL l $! goR r $! acc
    
    f' k a b = f (w2i k) a b

-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is
-- evaluated before using the result in the next application. This
-- function is strict in the starting value.

foldrWithKey' f z = start
  where
    start (IntMap (WordMap Empty)) = z
    start (IntMap (WordMap (NonEmpty min minV Tip))) = f' min minV $! z
    start (IntMap (WordMap (NonEmpty min minV (Bin max maxV l r))))
        | w2i (xor min max) < 0 = goR r $! f' max maxV $! f' min minV $! goL l $! z
        | otherwise = f' min minV $! goL l $! goR r $! f' max maxV $! z
    
    goL Tip acc = acc
    goL (Bin max maxV l r) acc = goL l $! goR r $! f' max maxV $! acc
    
    goR Tip acc = acc
    goR (Bin min minV l r) acc = f' min minV $! goL l $! goR r $! acc
    
    f' k a b = f (w2i k) a b

-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is
-- evaluated before using the result in the next application. This
-- function is strict in the starting value.
