So, here is my awkward code implementing the HashTable chain in Haskell.
{-# LANGUAGE FlexibleInstances #-} import Data.Array(Array(..), array, bounds, elems, (//), (!)) import Data.List(foldl') import Data.Char import Control.Monad.State class HashTranform a where hashPrepare :: a -> Integer instance HashTranform Integer where hashPrepare = id instance HashTranform String where hashPrepare cs = fromIntegral (foldl' (flip ((+) . ord)) 0 cs) divHashForSize :: (HashTranform a) => Integer -> a -> Integer divHashForSize sz k = 1 + (hashPrepare k) `mod` sz type Chain kv = [(k, v)] chainWith :: (Eq k) => Chain kv -> (k, v) -> Chain kv chainWith cs p@ (k, v) = if (null after) then p:cs else before ++ p:(tail after) where (before, after) = break ((== k) . fst) cs chainWithout :: (Eq k) => Chain kv -> k -> Chain kv chainWithout cs k = filter ((/= k) . fst) cs data Hash kv = Hash { hashFunc :: (k -> Integer) , chainTable :: Array Integer (Chain kv) } --type HState kv = State (Hash kv) instance (Show k, Show v) => Show (Hash kv) where show = show . concat . elems . chainTable type HashFuncForSize k = Integer -> k -> Integer createHash :: HashFuncForSize k -> Integer -> Hash kv createHash hs sz = Hash (hs sz) (array (1, sz) [(i, []) | i <- [1..sz]]) withSlot :: Hash kv -> k -> (Chain kv -> Chain kv) -> Hash kv withSlot hk op | rows < hashed = h | otherwise = Hash hf (ht // [(hashed, op (ht!hashed))]) where hf = hashFunc h ht = chainTable h rows = snd (bounds ht) hashed = hf k insert' :: (Eq k) => Hash kv -> (k, v) -> Hash kv insert' h p@ (k, v) = withSlot hk (flip chainWith p) delete' :: (Eq k) => Hash kv -> k -> Hash kv delete' hk = withSlot hk (flip chainWithout k) insert :: (Eq k) => Hash kv -> Chain kv -> Hash kv insert src pairs = foldl' insert' src pairs delete :: (Eq k) => Hash kv -> [k] -> Hash kv delete src keys = foldl' delete' src keys search :: (Eq k) => k -> Hash kv -> Maybe v search kh | rows < hashed = Nothing | otherwise = k `lookup` (ht!hashed) where hf = hashFunc h ht = chainTable h rows = snd (bounds ht) hashed = hf k
The problem is that I do not want this to be like this:
new = intHash `insert` [(1112, "uygfd"), (211, "catdied")] new' = new `delete` [(1112, "uygfd")]
I believe that it somehow changed with the help of State Monad, but after reading the online tutorials, I could not understand how exactly this is done.
So, you could show me how to implement at least insert, delete, search, or any of them to provide exposure.
source share