{-# 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 -- | The monad type associated with a given reference type. -- eg, IO for IORefs, ST for STRefs. -- Need to consider if Functional Dependencies will yield better type inference or not. 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' #-}