stateref-0.3: src/Data/MRef/Instances/STM.hs
{-# LANGUAGE
CPP,
MultiParamTypeClasses,
FlexibleInstances
#-}
-- |This module exports no new symbols of its own. It defines
-- basic class instances for creating, reading, and writing 'TVar's and
-- (if available) 'TMVar's, and re-exports the types for which it defines
-- instances as well as the 'atomically' function, which is indispensible
-- when playing with this stuff in ghci.
module Data.MRef.Instances.STM
( STM
#ifdef useTMVar
, TMVar
#endif
, TVar
, atomically
) where
import Data.MRef.Types
import Data.StateRef (readReference, writeReference, newReference)
import Data.StateRef.Instances.STM ()
import Control.Concurrent.STM
-- MRef STM in IO monad
instance NewMRef (MRef STM a) IO a where
#ifdef useTMVar
newMReference = fmap MRef . newTMVarIO
newEmptyMReference = fmap MRef newEmptyTMVarIO
#else
newMReference = fmap MRef . newTVarIO . Just
newEmptyMReference = fmap MRef (newTVarIO Nothing)
#endif
instance TakeMRef (MRef STM a) IO a where
takeMReference (MRef ref) = atomically (takeMReference ref)
instance PutMRef (MRef STM a) IO a where
putMReference (MRef ref) = atomically . putMReference ref
#ifdef useTMVar
--TMVar in STM monad
instance HasMRef STM where
newMRef x = fmap MRef (newTMVar x)
newEmptyMRef = fmap MRef newEmptyTMVar
instance NewMRef (TMVar a) STM a where
newMReference = newTMVar
newEmptyMReference = newEmptyTMVar
instance TakeMRef (TMVar a) STM a where
takeMReference = takeTMVar
instance PutMRef (TMVar a) STM a where
putMReference = putTMVar
-- TMVar in IO monad
instance NewMRef (TMVar a) IO a where
newMReference = newTMVarIO
newEmptyMReference = newEmptyTMVarIO
instance TakeMRef (TMVar a) IO a where
takeMReference = atomically . takeMReference
instance PutMRef (TMVar a) IO a where
putMReference ref = atomically . putMReference ref
#endif
-- incidental instances, which may occasionally be handy in a pinch
-- TVars containing "Maybe" values in STM monad.
-- Also use as default if TMVar isn't available.
#ifndef useTMVar
instance HasMRef STM where
newMRef x = fmap MRef (newTVar (Just x))
newEmptyMRef = fmap MRef (newTVar Nothing)
#endif
instance NewMRef (TVar (Maybe a)) STM a where
newMReference = newReference . Just
newEmptyMReference = newReference Nothing
instance TakeMRef (TVar (Maybe a)) STM a where
takeMReference ref = do
x <- readReference ref
case x of
Nothing -> retry
Just x -> do
writeReference ref Nothing
return x
instance PutMRef (TVar (Maybe a)) STM a where
putMReference ref val = do
x <- readReference ref
case x of
Nothing -> writeReference ref (Just val)
Just x -> retry
-- TVars containing "Maybe" values in IO monad
instance NewMRef (TVar (Maybe a)) IO a where
newMReference = newReference . Just
newEmptyMReference = newReference Nothing
instance TakeMRef (TVar (Maybe a)) IO a where
takeMReference = atomically . takeMReference
instance PutMRef (TVar (Maybe a)) IO a where
putMReference ref = atomically . putMReference ref