{-# LANGUAGE GADTs#-} module Data.HMemDb.References (CRef(CRef), Ref(Ref, refContent, refIndex), cRefIndex, deCRef, deRef, readCRef) where import Control.Concurrent.STM (TVar, readTVar) import Control.Monad.Trans.Maybe (MaybeT(MaybeT)) import Data.Function (on) import Data.Map (Map) import Data.HMemDb.MapTVar (MS, readTVarMap) data Ref r = Ref {refContent :: TVar (Maybe r), refIndex :: Integer} instance Eq (Ref r) where (==) = (==) `on` refIndex instance Ord (Ref r) where compare = compare `on` refIndex deRef :: Ref r -> MS r deRef ref = MaybeT $ readTVar $ refContent ref data CRef a where CRef :: Ref r -> (r -> MS a) -> CRef a cRefIndex :: CRef a -> Integer cRefIndex (CRef ref _) = refIndex ref instance Eq (CRef a) where (==) = (==) `on` cRefIndex instance Ord (CRef a) where compare = compare `on` cRefIndex deCRef :: CRef a -> MS a deCRef (CRef ref to) = deRef ref >>= to readCRef :: (r -> MS a) -> TVar (Map Integer (TVar (Maybe r))) -> Integer -> MS (CRef a) readCRef to tv i = do v <- readTVarMap tv i return $ CRef (Ref {refContent = v, refIndex = i}) to