stateref-0.2.1.1: src/Data/StateRef/Instances/STM.hs
{-
- ``Data/StateRef/Instances/STM''
- (c) 2008 Cook, J. MR SSD, Inc.
-}
{-# LANGUAGE
CPP,
MultiParamTypeClasses,
FlexibleInstances,
IncoherentInstances
#-}
-- |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.
--
-- Note that this module declares incoherent instances. The universe should
-- refrain from imploding on itself as long as you don't define
-- \"instance MonadIO STM\". However, hugs doesn't seem to support
-- overlapping instances, so I may have to give up on the dream of MonadIO
-- everywhere, or introduce some major conditional compilation stuff. (or
-- abandon hugs support)
module Data.StateRef.Instances.STM
( STM
, TVar
#ifdef useTMVar
, TMVar
#endif
, atomically
) where
import Data.StateRef.Classes
import Control.Monad.Trans
import Control.Concurrent.STM
-- (STM a) in STM and IO-compatible monads
instance ReadRef (STM a) STM a where
readRef = id
instance MonadIO m => ReadRef (STM a) m a where
readRef = liftIO . atomically
-- TVar in STM monad
instance DefaultStateRef (TVar a) STM a
instance NewRef (TVar a) STM a where
newRef = newTVar
instance ReadRef (TVar a) STM a where
readRef = readTVar
instance WriteRef (TVar a) STM a where
writeRef = writeTVar
instance ModifyRef (TVar a) STM a
-- TVar in IO-compatible monads
instance MonadIO m => NewRef (TVar a) m a where
newRef = liftIO . newTVarIO
instance MonadIO m => ReadRef (TVar a) m a where
readRef = liftIO . atomically . readRef
instance MonadIO m => WriteRef (TVar a) m a where
writeRef ref = liftIO . atomically . writeRef ref
instance MonadIO m => ModifyRef (TVar a) m a where
modifyRef ref = liftIO . atomically . modifyRef ref
#ifdef useTMVar
-- TMVar in STM monad
instance NewRef (TMVar a) STM (Maybe a) where
newRef Nothing = newEmptyTMVar
newRef (Just x) = newTMVar x
instance ReadRef (TMVar a) STM (Maybe a) where
readRef tmv = fmap Just (readTMVar tmv) `orElse` return Nothing
-- TMVar in IO-compatible monad
instance MonadIO m => NewRef (TMVar a) m (Maybe a) where
newRef Nothing = liftIO newEmptyTMVarIO
newRef (Just x) = liftIO (newTMVarIO x)
instance MonadIO m => ReadRef (TMVar a) m (Maybe a) where
readRef = liftIO . atomically . readRef
#endif