{-# LANGUAGE CPP #-} #ifdef LANGUAGE_DefaultSignatures {-# LANGUAGE DefaultSignatures #-} #endif {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} {- | Copyright : (c) Andy Sonnenburg 2013 License : BSD3 Maintainer : andy22286@gmail.com -} module Data.Ref.Class ( Ref (..) ) where #ifdef MODULE_Control_Monad_ST_Safe import Control.Monad.ST.Safe import qualified Control.Monad.ST.Lazy.Safe as Lazy #else import Control.Monad.ST import qualified Control.Monad.ST.Lazy as Lazy #endif import Control.Monad.Trans.Class import Control.Monad.Trans.Cont import Control.Monad.Trans.Error import Control.Monad.Trans.Identity import Control.Monad.Trans.List import Control.Monad.Trans.Maybe import qualified Control.Monad.Trans.RWS.Lazy as Lazy import qualified Control.Monad.Trans.RWS.Strict as Strict import Control.Monad.Trans.Reader import qualified Control.Monad.Trans.State.Lazy as Lazy import qualified Control.Monad.Trans.State.Strict as Strict import qualified Control.Monad.Trans.Writer.Lazy as Lazy import qualified Control.Monad.Trans.Writer.Strict as Strict import Data.IORef import Data.Monoid (Monoid) import Data.STRef import qualified Data.STRef.Lazy as Lazy class Monad m => Ref ref a m where newRef :: a -> m (ref a) readRef :: ref a -> m a writeRef :: ref a -> a -> m () modifyRef :: ref a -> (a -> a) -> m () modifyRef' :: ref a -> (a -> a) -> m () #ifdef LANGUAGE_DefaultSignatures default newRef :: (MonadTrans t, Ref ref a m) => a -> t m (ref a) newRef = lift . newRef default readRef :: (MonadTrans t, Ref ref a m) => ref a -> t m a readRef = lift . readRef default writeRef :: (MonadTrans t, Ref ref a m) => ref a -> a -> t m () writeRef ref = lift . writeRef ref #endif modifyRef ref f = readRef ref >>= writeRef ref . f modifyRef' ref f = readRef ref >>= \ a -> writeRef ref $! f a instance Ref IORef a IO where newRef = newIORef readRef = readIORef writeRef = writeIORef modifyRef = modifyIORef #ifdef FUNCTION_Data_IORef_modifyRef_ modifyRef' = modifyIORef' #endif instance Ref (STRef s) a (ST s) where newRef = newSTRef readRef = readSTRef writeRef = writeSTRef modifyRef = modifySTRef #ifdef FUNCTION_Data_STRef_modifyRef_ modifyRef' = modifySTRef' #endif instance Ref (Lazy.STRef s) a (Lazy.ST s) where newRef = Lazy.newSTRef readRef = Lazy.readSTRef writeRef = Lazy.writeSTRef modifyRef = Lazy.modifySTRef instance Ref ref a m => Ref ref a (ContT r m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance (Ref ref a m, Error e) => Ref ref a (ErrorT e m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (IdentityT m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (ListT m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (MaybeT m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance (Ref ref a m, Monoid w) => Ref ref a (Lazy.RWST r w s m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance (Ref ref a m, Monoid w) => Ref ref a (Strict.RWST r w s m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (ReaderT r m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (Lazy.StateT s m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance Ref ref a m => Ref ref a (Strict.StateT s m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance (Ref ref a m, Monoid w) => Ref ref a (Lazy.WriterT w m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref instance (Ref ref a m, Monoid w) => Ref ref a (Strict.WriterT w m) where #ifndef LANGUAGE_DefaultSignatures newRef = lift . newRef readRef = lift . readRef writeRef ref = lift . writeRef ref #endif modifyRef ref = lift . modifyRef ref modifyRef' ref = lift . modifyRef' ref