module Data.STRef.Persistent (
STRef
, asInt
, MonadRef(..)
) where
import Control.Monad.State
import Control.Monad.Ref
import Control.Monad.ST.Persistent.Internal
import Data.IntMap as IntMap
import Data.Maybe
import Unsafe.Coerce
newtype STRef s a = STRef Int
deriving (Eq, Show)
asInt :: STRef s a -> Int
asInt (STRef i) = i
newSTRef :: Monad m => a -> STT s m (STRef s a)
newSTRef x = STT $ do
s <- get
let i = next s
heap' = insert i (unsafeCoerce x) (heap s)
next' = next s + 1
put $ s { heap = heap', next = next' }
return (STRef i)
readSTRef :: Monad m => STRef s a -> STT s m a
readSTRef (STRef i) = STT $
return . unsafeCoerce . fromJust . IntMap.lookup i =<< gets heap
writeSTRef :: Monad m => STRef s a -> a -> STT s m ()
writeSTRef (STRef i) x = STT $ do
s <- get
let heap' = insert i (unsafeCoerce x) (heap s)
put $ s { heap = heap' }
instance Monad m => MonadRef (STRef s) (STT s m) where
newRef = newSTRef
readRef = readSTRef
writeRef = writeSTRef