module Data.HashTable.Extended (
    getKeys
  , resetHashTable
  , AnyHashTable(..)
  ) where


import Data.Hashable ( Hashable )
import Data.HashTable.Class ( HashTable )
import qualified Data.HashTable.IO as HT


------------------------------------------------------------------------------

getKeys :: (HashTable h) => HT.IOHashTable h k v -> IO [k]
getKeys :: IOHashTable h k v -> IO [k]
getKeys IOHashTable h k v
ht = ([k] -> (k, v) -> IO [k]) -> [k] -> IOHashTable h k v -> IO [k]
forall (h :: * -> * -> * -> *) a k v.
HashTable h =>
(a -> (k, v) -> IO a) -> a -> IOHashTable h k v -> IO a
HT.foldM [k] -> (k, v) -> IO [k]
forall (m :: * -> *) a b. Monad m => [a] -> (a, b) -> m [a]
f [] IOHashTable h k v
ht
  where f :: [a] -> (a, b) -> m [a]
f ![a]
l !(a
k, b
_) = [a] -> m [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (a
k a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
l)

resetHashTable :: AnyHashTable -> IO ()
resetHashTable :: AnyHashTable -> IO ()
resetHashTable (AnyHashTable IOHashTable h k v
ht) = do
  [k]
keys <- IOHashTable h k v -> IO [k]
forall (h :: * -> * -> * -> *) k v.
HashTable h =>
IOHashTable h k v -> IO [k]
getKeys IOHashTable h k v
ht
  (k -> IO ()) -> [k] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\k
k -> IOHashTable h k v -> k -> (Maybe v -> (Maybe v, ())) -> IO ()
forall (h :: * -> * -> * -> *) k v a.
(HashTable h, Eq k, Hashable k) =>
IOHashTable h k v -> k -> (Maybe v -> (Maybe v, a)) -> IO a
HT.mutate IOHashTable h k v
ht k
k ((Maybe v, ()) -> Maybe v -> (Maybe v, ())
forall a b. a -> b -> a
const (Maybe v
forall a. Maybe a
Nothing, ()))) [k]
keys


data AnyHashTable where
  AnyHashTable :: (HashTable h, Eq k, Hashable k) => HT.IOHashTable h k v -> AnyHashTable