Ref-0.1.1.0: src/Data/Ref.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
module Data.Ref(Ref(..), module Data.Ref.CAS )where
{- -}
import qualified Data.IORef as IR
import qualified Data.STRef.Strict as SR
import Control.Monad.ST.Safe (ST)
import Data.Ref.CAS
import Control.Monad
{- I can't choose what sort of ref you give me,
nor can i change what the current monad is
so why bother using different operations for either?
also i'm only providing the stict versions of the data types as applicable
, though other instances that are sensible are welcome.
also worth thinking about how to support analogous generic api for concurrent operations
-}
class Ref ref where
type RefM ref :: * -> *
newRef :: a -> RefM ref (ref a)
newRef' :: a -> RefM ref (ref a)
readRef :: ref a -> RefM ref a
readRef' :: ref a -> RefM ref a
writeRef :: ref a -> a -> RefM ref ()
writeRef' :: ref a -> a -> RefM ref ()
modifyRef :: ref a -> (a-> a) -> RefM ref ()
modifyRef' :: ref a -> (a-> a) -> RefM ref ()
instance Ref IR.IORef where
type RefM IR.IORef = IO
newRef a = IR.newIORef a
{-# INLINE newRef #-}
newRef' !a = IR.newIORef $! a
{-# INLINE newRef' #-}
readRef a = IR.readIORef a
{-# INLINE readRef #-}
readRef' !r = IR.readIORef $! r
{-# INLINE readRef' #-}
writeRef r a = IR.writeIORef r a
{-# INLINE writeRef #-}
writeRef' !r !a =IR.writeIORef r $! a
{-# INLINE writeRef' #-}
modifyRef r f = IR.modifyIORef r f
{-# INLINE modifyRef #-}
modifyRef' r f = IR.modifyIORef' r f
{-# INLINE modifyRef' #-}
instance Ref (SR.STRef s) where
type RefM (SR.STRef s) = ST s
newRef a = SR.newSTRef a
{-# INLINE newRef #-}
newRef' !a = SR.newSTRef $! a
{-# INLINE newRef' #-}
readRef a = SR.readSTRef a
{-# INLINE readRef #-}
readRef' !r = SR.readSTRef $! r
{-# INLINE readRef' #-}
writeRef r a = SR.writeSTRef r a
{-# INLINE writeRef #-}
writeRef' !r !a =SR.writeSTRef r $! a
{-# INLINE writeRef' #-}
modifyRef r f = SR.modifySTRef r f
{-# INLINE modifyRef #-}
modifyRef' r f = SR.modifySTRef' r f
{-# INLINE modifyRef' #-}