{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-} -- | -- Module : Simulation.Aivika.Trans.Ref.Base.Strict -- Copyright : Copyright (c) 2009-2017, David Sorokin -- License : BSD3 -- Maintainer : David Sorokin -- Stability : experimental -- Tested with: GHC 8.0.1 -- -- This module defines a plain and more fast version of an updatable and strict reference -- that depends on the event queue but that doesn't supply with the signal notification. -- module Simulation.Aivika.Trans.Ref.Base.Strict (MonadRef(..), MonadRef0(..)) where import Data.IORef import Control.Monad import Control.Monad.Trans import Simulation.Aivika.Trans.Internal.Types import Simulation.Aivika.Trans.Observable -- | A monad within which we can create mutable references. class Monad m => MonadRef m where -- | The 'Ref' type represents a mutable variable similar to the 'IORef' variable -- but only dependent on the event queue, which allows synchronizing the reference -- with the model explicitly through the 'Event' monad. data Ref m a -- | Create a new reference. newRef :: a -> Simulation m (Ref m a) -- | Read the value of a reference. readRef :: Ref m a -> Event m a -- | Write a new value into the reference. writeRef :: Ref m a -> a -> Event m () -- | Mutate the contents of the reference. modifyRef :: Ref m a -> (a -> a) -> Event m () -- | Compare two references for equality. equalRef :: Ref m a -> Ref m a -> Bool instance MonadRef m => Eq (Ref m a) where {-# INLINE (==) #-} (==) = equalRef -- | A kind of reference that can be created within more low level computation than 'Simulation'. class MonadRef m => MonadRef0 m where -- | Create a new reference within more low level computation than 'Simulation'. newRef0 :: a -> m (Ref m a) instance (Monad m, MonadRef m) => Observable (Ref m) (Event m) where {-# INLINE readObservable #-} readObservable = readRef