{-# LANGUAGE TypeFamilies #-}

-- |
-- Module     : Simulation.Aivika.Distributed.Optimistic.Ref.Base.Lazy
-- Copyright  : Copyright (c) 2015-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 7.10.3
--
-- Here is an implementation of lazy mutable references, where
-- 'DIO' is an instance of 'MonadRef' and 'MonadRef0'.
--
module Simulation.Aivika.Distributed.Optimistic.Ref.Base.Lazy () where

import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.Ref.Base.Lazy

import Simulation.Aivika.Distributed.Optimistic.Internal.DIO
import qualified Simulation.Aivika.Distributed.Optimistic.Internal.Ref.Lazy as R

-- | The implementation of lazy mutable references.
instance MonadRef DIO where

  -- | The lazy mutable reference.
  newtype Ref DIO a = Ref { forall a. Ref DIO a -> Ref a
refValue :: R.Ref a }

  {-# INLINE newRef #-}
  newRef :: forall a. a -> Simulation DIO (Ref DIO a)
newRef = (Ref a -> Ref DIO a)
-> Simulation DIO (Ref a) -> Simulation DIO (Ref DIO a)
forall a b. (a -> b) -> Simulation DIO a -> Simulation DIO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ref a -> Ref DIO a
forall a. Ref a -> Ref DIO a
Ref (Simulation DIO (Ref a) -> Simulation DIO (Ref DIO a))
-> (a -> Simulation DIO (Ref a)) -> a -> Simulation DIO (Ref DIO a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Simulation DIO (Ref a)
forall a. a -> Simulation DIO (Ref a)
R.newRef 

  {-# INLINE readRef #-}
  readRef :: forall a. Ref DIO a -> Event DIO a
readRef (Ref Ref a
r) = Ref a -> Event DIO a
forall a. Ref a -> Event DIO a
R.readRef Ref a
r

  {-# INLINE writeRef #-}
  writeRef :: forall a. Ref DIO a -> a -> Event DIO ()
writeRef (Ref Ref a
r) = Ref a -> a -> Event DIO ()
forall a. Ref a -> a -> Event DIO ()
R.writeRef Ref a
r

  {-# INLINE modifyRef #-}
  modifyRef :: forall a. Ref DIO a -> (a -> a) -> Event DIO ()
modifyRef (Ref Ref a
r) = Ref a -> (a -> a) -> Event DIO ()
forall a. Ref a -> (a -> a) -> Event DIO ()
R.modifyRef Ref a
r

  {-# INLINE equalRef #-}
  equalRef :: forall a. Ref DIO a -> Ref DIO a -> Bool
equalRef (Ref Ref a
r1) (Ref Ref a
r2) = (Ref a
r1 Ref a -> Ref a -> Bool
forall a. Eq a => a -> a -> Bool
== Ref a
r2)

instance MonadRef0 DIO where

  {-# INLINE newRef0 #-}
  newRef0 :: forall a. a -> DIO (Ref DIO a)
newRef0 = (Ref a -> Ref DIO a) -> DIO (Ref a) -> DIO (Ref DIO a)
forall a b. (a -> b) -> DIO a -> DIO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ref a -> Ref DIO a
forall a. Ref a -> Ref DIO a
Ref (DIO (Ref a) -> DIO (Ref DIO a))
-> (a -> DIO (Ref a)) -> a -> DIO (Ref DIO a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> DIO (Ref a)
forall a. a -> DIO (Ref a)
R.newRef0