{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module Control.Monad.STM.Class
( MonadSTM(..)
, retry
, check
, orElse
, throwSTM
, catchSTM
, IsSTM
, toIsSTM
, fromIsSTM
) where
import Control.Applicative (Alternative(..))
import Control.Exception (Exception)
import Control.Monad (MonadPlus(..), unless)
import Control.Monad.Fail (MonadFail(..))
import Control.Monad.Reader (ReaderT)
import Control.Monad.Trans (lift)
import Control.Monad.Trans.Identity (IdentityT)
import Data.Kind (Type)
import qualified Control.Concurrent.STM as STM
import qualified Control.Monad.Catch as Ca
import qualified Control.Monad.RWS.Lazy as RL
import qualified Control.Monad.RWS.Strict as RS
import qualified Control.Monad.State.Lazy as SL
import qualified Control.Monad.State.Strict as SS
import qualified Control.Monad.Writer.Lazy as WL
import qualified Control.Monad.Writer.Strict as WS
class (Ca.MonadCatch stm, MonadPlus stm) => MonadSTM stm where
{-# MINIMAL
(newTVar | newTVarN)
, readTVar
, writeTVar
#-}
type TVar stm :: Type -> Type
newTVar :: a -> stm (TVar stm a)
newTVar = String -> a -> stm (TVar stm a)
forall (stm :: * -> *) a.
MonadSTM stm =>
String -> a -> stm (TVar stm a)
newTVarN String
""
newTVarN :: String -> a -> stm (TVar stm a)
newTVarN String
_ = a -> stm (TVar stm a)
forall (stm :: * -> *) a. MonadSTM stm => a -> stm (TVar stm a)
newTVar
readTVar :: TVar stm a -> stm a
writeTVar :: TVar stm a -> a -> stm ()
retry :: MonadSTM stm => stm a
retry :: stm a
retry = stm a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
check :: MonadSTM stm => Bool -> stm ()
check :: Bool -> stm ()
check Bool
b = Bool -> stm () -> stm ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
b stm ()
forall (stm :: * -> *) a. MonadSTM stm => stm a
retry
orElse :: MonadSTM stm => stm a -> stm a -> stm a
orElse :: stm a -> stm a -> stm a
orElse = stm a -> stm a -> stm a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
throwSTM :: (MonadSTM stm, Exception e) => e -> stm a
throwSTM :: e -> stm a
throwSTM = e -> stm a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
Ca.throwM
catchSTM :: (MonadSTM stm, Exception e) => stm a -> (e -> stm a) -> stm a
catchSTM :: stm a -> (e -> stm a) -> stm a
catchSTM = stm a -> (e -> stm a) -> stm a
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
Ca.catch
instance MonadSTM STM.STM where
type TVar STM.STM = STM.TVar
newTVar :: a -> STM (TVar STM a)
newTVar = a -> STM (TVar STM a)
forall a. a -> STM (TVar a)
STM.newTVar
readTVar :: TVar STM a -> STM a
readTVar = TVar STM a -> STM a
forall a. TVar a -> STM a
STM.readTVar
writeTVar :: TVar STM a -> a -> STM ()
writeTVar = TVar STM a -> a -> STM ()
forall a. TVar a -> a -> STM ()
STM.writeTVar
newtype IsSTM m a = IsSTM { IsSTM m a -> m a
unIsSTM :: m a }
deriving (a -> IsSTM m b -> IsSTM m a
(a -> b) -> IsSTM m a -> IsSTM m b
(forall a b. (a -> b) -> IsSTM m a -> IsSTM m b)
-> (forall a b. a -> IsSTM m b -> IsSTM m a) -> Functor (IsSTM m)
forall a b. a -> IsSTM m b -> IsSTM m a
forall a b. (a -> b) -> IsSTM m a -> IsSTM m b
forall (m :: * -> *) a b. Functor m => a -> IsSTM m b -> IsSTM m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> IsSTM m a -> IsSTM m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> IsSTM m b -> IsSTM m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> IsSTM m b -> IsSTM m a
fmap :: (a -> b) -> IsSTM m a -> IsSTM m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> IsSTM m a -> IsSTM m b
Functor, Functor (IsSTM m)
a -> IsSTM m a
Functor (IsSTM m)
-> (forall a. a -> IsSTM m a)
-> (forall a b. IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b)
-> (forall a b c.
(a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c)
-> (forall a b. IsSTM m a -> IsSTM m b -> IsSTM m b)
-> (forall a b. IsSTM m a -> IsSTM m b -> IsSTM m a)
-> Applicative (IsSTM m)
IsSTM m a -> IsSTM m b -> IsSTM m b
IsSTM m a -> IsSTM m b -> IsSTM m a
IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b
(a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c
forall a. a -> IsSTM m a
forall a b. IsSTM m a -> IsSTM m b -> IsSTM m a
forall a b. IsSTM m a -> IsSTM m b -> IsSTM m b
forall a b. IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b
forall a b c. (a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (IsSTM m)
forall (m :: * -> *) a. Applicative m => a -> IsSTM m a
forall (m :: * -> *) a b.
Applicative m =>
IsSTM m a -> IsSTM m b -> IsSTM m a
forall (m :: * -> *) a b.
Applicative m =>
IsSTM m a -> IsSTM m b -> IsSTM m b
forall (m :: * -> *) a b.
Applicative m =>
IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c
<* :: IsSTM m a -> IsSTM m b -> IsSTM m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
IsSTM m a -> IsSTM m b -> IsSTM m a
*> :: IsSTM m a -> IsSTM m b -> IsSTM m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
IsSTM m a -> IsSTM m b -> IsSTM m b
liftA2 :: (a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> IsSTM m a -> IsSTM m b -> IsSTM m c
<*> :: IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
IsSTM m (a -> b) -> IsSTM m a -> IsSTM m b
pure :: a -> IsSTM m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> IsSTM m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (IsSTM m)
Applicative, Applicative (IsSTM m)
IsSTM m a
Applicative (IsSTM m)
-> (forall a. IsSTM m a)
-> (forall a. IsSTM m a -> IsSTM m a -> IsSTM m a)
-> (forall a. IsSTM m a -> IsSTM m [a])
-> (forall a. IsSTM m a -> IsSTM m [a])
-> Alternative (IsSTM m)
IsSTM m a -> IsSTM m a -> IsSTM m a
IsSTM m a -> IsSTM m [a]
IsSTM m a -> IsSTM m [a]
forall a. IsSTM m a
forall a. IsSTM m a -> IsSTM m [a]
forall a. IsSTM m a -> IsSTM m a -> IsSTM m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: * -> *). Alternative m => Applicative (IsSTM m)
forall (m :: * -> *) a. Alternative m => IsSTM m a
forall (m :: * -> *) a. Alternative m => IsSTM m a -> IsSTM m [a]
forall (m :: * -> *) a.
Alternative m =>
IsSTM m a -> IsSTM m a -> IsSTM m a
many :: IsSTM m a -> IsSTM m [a]
$cmany :: forall (m :: * -> *) a. Alternative m => IsSTM m a -> IsSTM m [a]
some :: IsSTM m a -> IsSTM m [a]
$csome :: forall (m :: * -> *) a. Alternative m => IsSTM m a -> IsSTM m [a]
<|> :: IsSTM m a -> IsSTM m a -> IsSTM m a
$c<|> :: forall (m :: * -> *) a.
Alternative m =>
IsSTM m a -> IsSTM m a -> IsSTM m a
empty :: IsSTM m a
$cempty :: forall (m :: * -> *) a. Alternative m => IsSTM m a
$cp1Alternative :: forall (m :: * -> *). Alternative m => Applicative (IsSTM m)
Alternative, Applicative (IsSTM m)
a -> IsSTM m a
Applicative (IsSTM m)
-> (forall a b. IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b)
-> (forall a b. IsSTM m a -> IsSTM m b -> IsSTM m b)
-> (forall a. a -> IsSTM m a)
-> Monad (IsSTM m)
IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b
IsSTM m a -> IsSTM m b -> IsSTM m b
forall a. a -> IsSTM m a
forall a b. IsSTM m a -> IsSTM m b -> IsSTM m b
forall a b. IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b
forall (m :: * -> *). Monad m => Applicative (IsSTM m)
forall (m :: * -> *) a. Monad m => a -> IsSTM m a
forall (m :: * -> *) a b.
Monad m =>
IsSTM m a -> IsSTM m b -> IsSTM m b
forall (m :: * -> *) a b.
Monad m =>
IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> IsSTM m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> IsSTM m a
>> :: IsSTM m a -> IsSTM m b -> IsSTM m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
IsSTM m a -> IsSTM m b -> IsSTM m b
>>= :: IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
IsSTM m a -> (a -> IsSTM m b) -> IsSTM m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (IsSTM m)
Monad, Monad (IsSTM m)
Alternative (IsSTM m)
IsSTM m a
Alternative (IsSTM m)
-> Monad (IsSTM m)
-> (forall a. IsSTM m a)
-> (forall a. IsSTM m a -> IsSTM m a -> IsSTM m a)
-> MonadPlus (IsSTM m)
IsSTM m a -> IsSTM m a -> IsSTM m a
forall a. IsSTM m a
forall a. IsSTM m a -> IsSTM m a -> IsSTM m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
forall (m :: * -> *). MonadPlus m => Monad (IsSTM m)
forall (m :: * -> *). MonadPlus m => Alternative (IsSTM m)
forall (m :: * -> *) a. MonadPlus m => IsSTM m a
forall (m :: * -> *) a.
MonadPlus m =>
IsSTM m a -> IsSTM m a -> IsSTM m a
mplus :: IsSTM m a -> IsSTM m a -> IsSTM m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
IsSTM m a -> IsSTM m a -> IsSTM m a
mzero :: IsSTM m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => IsSTM m a
$cp2MonadPlus :: forall (m :: * -> *). MonadPlus m => Monad (IsSTM m)
$cp1MonadPlus :: forall (m :: * -> *). MonadPlus m => Alternative (IsSTM m)
MonadPlus, Monad (IsSTM m)
e -> IsSTM m a
Monad (IsSTM m)
-> (forall e a. Exception e => e -> IsSTM m a)
-> MonadThrow (IsSTM m)
forall e a. Exception e => e -> IsSTM m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (IsSTM m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> IsSTM m a
throwM :: e -> IsSTM m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> IsSTM m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (IsSTM m)
Ca.MonadThrow, MonadThrow (IsSTM m)
MonadThrow (IsSTM m)
-> (forall e a.
Exception e =>
IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a)
-> MonadCatch (IsSTM m)
IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a
forall e a.
Exception e =>
IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall (m :: * -> *). MonadCatch m => MonadThrow (IsSTM m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a
catch :: IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
IsSTM m a -> (e -> IsSTM m a) -> IsSTM m a
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (IsSTM m)
Ca.MonadCatch)
deriving instance MonadFail m => MonadFail (IsSTM m)
toIsSTM :: MonadSTM m => m a -> IsSTM m a
toIsSTM :: m a -> IsSTM m a
toIsSTM = m a -> IsSTM m a
forall (m :: * -> *) a. m a -> IsSTM m a
IsSTM
fromIsSTM :: MonadSTM m => IsSTM m a -> m a
fromIsSTM :: IsSTM m a -> m a
fromIsSTM = IsSTM m a -> m a
forall (m :: * -> *) a. IsSTM m a -> m a
unIsSTM
instance MonadSTM m => MonadSTM (IsSTM m) where
type TVar (IsSTM m) = TVar m
newTVar :: a -> IsSTM m (TVar (IsSTM m) a)
newTVar = m (TVar m a) -> IsSTM m (TVar m a)
forall (m :: * -> *) a. MonadSTM m => m a -> IsSTM m a
toIsSTM (m (TVar m a) -> IsSTM m (TVar m a))
-> (a -> m (TVar m a)) -> a -> IsSTM m (TVar m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m (TVar m a)
forall (stm :: * -> *) a. MonadSTM stm => a -> stm (TVar stm a)
newTVar
newTVarN :: String -> a -> IsSTM m (TVar (IsSTM m) a)
newTVarN String
n = m (TVar m a) -> IsSTM m (TVar m a)
forall (m :: * -> *) a. MonadSTM m => m a -> IsSTM m a
toIsSTM (m (TVar m a) -> IsSTM m (TVar m a))
-> (a -> m (TVar m a)) -> a -> IsSTM m (TVar m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a -> m (TVar m a)
forall (stm :: * -> *) a.
MonadSTM stm =>
String -> a -> stm (TVar stm a)
newTVarN String
n
readTVar :: TVar (IsSTM m) a -> IsSTM m a
readTVar = m a -> IsSTM m a
forall (m :: * -> *) a. MonadSTM m => m a -> IsSTM m a
toIsSTM (m a -> IsSTM m a) -> (TVar m a -> m a) -> TVar m a -> IsSTM m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar m a -> m a
forall (stm :: * -> *) a. MonadSTM stm => TVar stm a -> stm a
readTVar
writeTVar :: TVar (IsSTM m) a -> a -> IsSTM m ()
writeTVar TVar (IsSTM m) a
v = m () -> IsSTM m ()
forall (m :: * -> *) a. MonadSTM m => m a -> IsSTM m a
toIsSTM (m () -> IsSTM m ()) -> (a -> m ()) -> a -> IsSTM m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar m a -> a -> m ()
forall (stm :: * -> *) a. MonadSTM stm => TVar stm a -> a -> stm ()
writeTVar TVar m a
TVar (IsSTM m) a
v
#define INSTANCE(T,C,F) \
instance C => MonadSTM (T stm) where { \
type TVar (T stm) = TVar stm ; \
\
newTVar = lift . newTVar ; \
newTVarN n = lift . newTVarN n ; \
readTVar = lift . readTVar ; \
writeTVar v = lift . writeTVar v }
INSTANCE(ReaderT r, MonadSTM stm, id)
INSTANCE(IdentityT, MonadSTM stm, id)
INSTANCE(WL.WriterT w, (MonadSTM stm, Monoid w), fst)
INSTANCE(WS.WriterT w, (MonadSTM stm, Monoid w), fst)
INSTANCE(SL.StateT s, MonadSTM stm, fst)
INSTANCE(SS.StateT s, MonadSTM stm, fst)
INSTANCE(RL.RWST r w s, (MonadSTM stm, Monoid w), (\(a,_,_) -> a))
INSTANCE(RS.RWST r w s, (MonadSTM stm, Monoid w), (\(a,_,_) -> a))
#undef INSTANCE