determineUnconsumed :: Set JSONPath -> Value -> [JSONPath]
determineUnconsumed ((<> Set.singleton []) -> consumed) = Set.toList . execWriter . go []
  where
    go :: JSONPath -> Value -> Writer (Set JSONPath) ()
    go path value
      | path `notMember` consumed = tell (Set.singleton path)
      | otherwise = case value of
          Number _ -> return ()
          String _ -> return ()
          Bool _ -> return ()
          Null -> return ()
          Object o -> do
            forM_ (KeyMap.toList o) $ \ (Key.toText -> k, v) -> do
              unless ("_" `T.isPrefixOf` k) $ do
                go (Key k : path) v
          Array xs -> do
            forM_ (zip [0..] $ V.toList xs) $ \ (n, v) -> do
              go (Index n : path) v
determineUnconsumed :: Set JSONPath -> Value -> [JSONPath]
determineUnconsumed ((<> Set.singleton []) -> consumed) = Set.toList . execWriter . go []
  where
    go :: JSONPath -> Value -> Writer (Set JSONPath) ()
    go path value
      | path `notMember` consumed = tell (Set.singleton path)
      | otherwise = case value of
          Number _ -> return ()
          String _ -> return ()
          Bool _ -> return ()
          Null -> return ()
          Object o -> do
            forM_ (KeyMap.toList o) $ \ (Key.toText -> k, v) -> do
              unless ("_" `T.isPrefixOf` k) $ do
                go (Key k : path) v
          Array xs -> do
            forM_ (zip [0..] $ V.toList xs) $ \ (n, v) -> do
              go (Index n : path) v
determineUnconsumed ((<> Set.singleton []) -> consumed) = Set.toList . execWriter . go []
  where
    go :: JSONPath -> Value -> Writer (Set JSONPath) ()
    go path value
      | path `notMember` consumed = tell (Set.singleton path)
      | otherwise = case value of
          Number _ -> return ()
          String _ -> return ()
          Bool _ -> return ()
          Null -> return ()
          Object o -> do
            forM_ (KeyMap.toList o) $ \ (Key.toText -> k, v) -> do
              unless ("_" `T.isPrefixOf` k) $ do
                go (Key k : path) v
          Array xs -> do
            forM_ (zip [0..] $ V.toList xs) $ \ (n, v) -> do
              go (Index n : path) v