{-# LANGUAGE GADTs#-} module Data.HMemDb.References (CRef(CRef), Ref(Ref, refContent, refIndex), deCRef, deRef) where import Control.Concurrent.STM (TVar, readTVar) import Control.Monad.Trans.Class (lift) import Data.Function (on) import Data.HMemDb.Binary (MS) import Data.HMemDb.Utils (liftMaybe) 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 = lift (readTVar $ refContent ref) >>= liftMaybe data CRef a where CRef :: Ref r -> (r -> MS a) -> CRef a deCRef :: CRef a -> MS a deCRef (CRef ref to) = deRef ref >>= to