hashtables-1.0.0.0: src/Data/HashTable/Class.hs
{-# LANGUAGE BangPatterns #-}
-- | This module contains a 'HashTable' typeclass for the hash table
-- implementations in this package. This allows you to provide functions which
-- will work for any hash table implementation in this collection.
--
-- It is recommended to create a concrete type alias in your code when using this
-- package, i.e.:
--
-- > import qualified Data.HashTable.IO as H
-- >
-- > type HashTable k v = H.BasicHashTable k v
-- >
-- > foo :: IO (HashTable Int Int)
-- > foo = do
-- > ht <- H.new
-- > H.insert ht 1 1
-- > return ht
--
-- or
--
-- > import qualified Data.HashTable.ST.Cuckoo as C
-- > import qualified Data.HashTable.Class as H
-- >
-- > type HashTable s k v = C.HashTable s k v
-- >
-- > foo :: ST s (HashTable s k v)
-- > foo = do
-- > ht <- H.new
-- > H.insert ht 1 1
-- > return ht
--
-- Firstly, this makes it easy to switch to a different hash table
-- implementation, and secondly, using a concrete type rather than leaving your
-- functions abstract in the 'HashTable' class should allow GHC to optimize
-- away the typeclass dictionaries.
--
-- Note that the functions in this typeclass are in the 'ST' monad; if you want
-- hash tables in 'IO', use the convenience wrappers in "Data.HashTable.IO".
--
module Data.HashTable.Class
( HashTable(..)
, fromList
, toList
) where
import Control.Monad.ST
import Data.Hashable
import Prelude hiding (mapM_)
-- | A typeclass for hash tables in the 'ST' monad. The operations on these
-- hash tables are typically both key- and value-strict.
class HashTable h where
-- | Creates a new, default-sized hash table. /O(1)/.
new :: ST s (h s k v)
-- | Creates a new hash table sized to hold @n@ elements. /O(n)/.
newSized :: Int -> ST s (h s k v)
-- | Inserts a key/value mapping into a hash table, replacing any existing
-- mapping for that key.
--
-- /O(n)/ worst case, /O(1)/ amortized.
insert :: (Eq k, Hashable k) => h s k v -> k -> v -> ST s ()
-- | Deletes a key-value mapping from a hash table. /O(n)/ worst case,
-- /O(1)/ amortized.
delete :: (Eq k, Hashable k) => h s k v -> k -> ST s ()
-- | Looks up a key-value mapping in a hash table. /O(n)/ worst case,
-- (/O(1)/ for cuckoo hash), /O(1)/ amortized.
lookup :: (Eq k, Hashable k) => h s k v -> k -> ST s (Maybe v)
-- | A strict fold over the key-value records of a hash table in the 'ST'
-- monad. /O(n)/.
foldM :: (a -> (k,v) -> ST s a) -> a -> h s k v -> ST s a
-- | A side-effecting map over the key-value records of a hash
-- table. /O(n)/.
mapM_ :: ((k,v) -> ST s b) -> h s k v -> ST s ()
-- | Computes the overhead (in words) per key-value mapping. Used for
-- debugging, etc; time complexity depends on the underlying hash table
-- implementation. /O(n)/.
computeOverhead :: h s k v -> ST s Double
------------------------------------------------------------------------------
-- | Create a hash table from a list of key-value pairs. /O(n)/.
fromList :: (HashTable h, Eq k, Hashable k) => [(k,v)] -> ST s (h s k v)
fromList l = do
ht <- newSized (length l)
go ht l
where
go ht = go'
where
go' [] = return ht
go' ((!k,!v):xs) = do
insert ht k v
go' xs
{-# INLINE fromList #-}
------------------------------------------------------------------------------
-- | Given a hash table, produce a list of key-value pairs. /O(n)/.
toList :: (HashTable h) => h s k v -> ST s [(k,v)]
toList ht = do
l <- foldM f [] ht
return l
where
f !l !t = return (t:l)
{-# INLINE toList #-}