{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances #-} -- | -- Module : Simulation.Aivika.IO.Ref.Base -- Copyright : Copyright (c) 2009-2015, David Sorokin -- License : BSD3 -- Maintainer : David Sorokin -- Stability : experimental -- Tested with: GHC 7.10.1 -- -- The 'MonadIO'-based monad can be an instance of 'MonadRef'. -- module Simulation.Aivika.IO.Ref.Base () where import Data.IORef import Control.Monad import Control.Monad.Trans import Simulation.Aivika.Trans.Internal.Types import Simulation.Aivika.Trans.Ref.Base import Simulation.Aivika.Trans.Template -- | The 'MonadIO' based monad is an instance of 'MonadRef'. instance (MonadIO m, MonadTemplate m) => MonadRef m where {-# SPECIALISE instance MonadRef IO #-} -- | A type safe wrapper for the 'IORef' reference. newtype Ref m a = Ref { refValue :: IORef a } {-# INLINE newRef #-} newRef a = Simulation $ \r -> do x <- liftIO $ newIORef a return Ref { refValue = x } {-# INLINE readRef #-} readRef r = Event $ \p -> liftIO $ readIORef (refValue r) {-# INLINE writeRef #-} writeRef r a = Event $ \p -> a `seq` liftIO $ writeIORef (refValue r) a {-# INLINE modifyRef #-} modifyRef r f = Event $ \p -> do a <- liftIO $ readIORef (refValue r) let b = f a b `seq` liftIO $ writeIORef (refValue r) b {-# INLINE equalRef #-} equalRef (Ref r1) (Ref r2) = (r1 == r2) -- | The 'MonadIO' based monad is an instance of 'MonadRef0'. instance (MonadIO m, MonadTemplate m) => MonadRef0 m where {-# SPECIALISE instance MonadRef0 IO #-} {-# INLINE newRef0 #-} newRef0 a = do x <- liftIO $ newIORef a return Ref { refValue = x }