-- |
-- Module      :  Case.Hashable.Cuckoo
-- Copyright   :  (c) OleksandrZhabenko 2021
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- A library that can be used as a @case ... of@ constuction analogue for the Hashable keys.
-- For the large lists is expected to be more time efficient than CaseBi.Arr.getBFst' analogue.
-- If you plan to use it together with the former one, please, use qualified import to avoid names ambiguity.


{-# LANGUAGE MagicHash, UnboxedTuples #-}

module Case.Hashable.Cuckoo (
  getBFstL'
) where

import qualified Data.HashTable.ST.Cuckoo as C
import qualified Data.HashTable.Class as H (fromList)
import GHC.ST
import GHC.Magic (runRW# )
import Data.Maybe (fromMaybe)
import Data.Hashable (Hashable(..))

getBFstL' :: (Eq k, Hashable k) => v -> [(k, v)] -> k -> v
getBFstL' :: v -> [(k, v)] -> k -> v
getBFstL' v
def [(k, v)]
pairs k
key = v -> Maybe v -> v
forall a. a -> Maybe a -> a
fromMaybe v
def
  ((\(ST STRep RealWorld (Maybe v)
st_rep) -> case STRep RealWorld (Maybe v) -> (# State# RealWorld, Maybe v #)
forall o. (State# RealWorld -> o) -> o
runRW# STRep RealWorld (Maybe v)
st_rep of (# State# RealWorld
_, Maybe v
a #) -> Maybe v
a) (ST RealWorld (Maybe v) -> Maybe v)
-> (k -> ST RealWorld (Maybe v)) -> k -> Maybe v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. -- Actually is rewritten from the GHC.ST.runST to remove the forall constraint
    [(k, v)] -> k -> ST RealWorld (Maybe v)
forall k v s. (Eq k, Hashable k) => [(k, v)] -> k -> ST s (Maybe v)
lookup2 [(k, v)]
pairs (k -> Maybe v) -> k -> Maybe v
forall a b. (a -> b) -> a -> b
$ k
key)

lookup2 :: [(k, v)] -> k -> ST s (Maybe v)
lookup2 [(k, v)]
pairs k
key = [(k, v)] -> ST s (HashTable s k v)
forall (h :: * -> * -> * -> *) k v s.
(HashTable h, Eq k, Hashable k) =>
[(k, v)] -> ST s (h s k v)
H.fromList [(k, v)]
pairs ST s (HashTable s k v)
-> (HashTable s k v -> ST s (Maybe v)) -> ST s (Maybe v)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \HashTable s k v
ht -> HashTable s k v -> k -> ST s (Maybe v)
forall k s v.
(Eq k, Hashable k) =>
HashTable s k v -> k -> ST s (Maybe v)
C.lookup HashTable s k v
ht k
key
{-# INLINE lookup2 #-}