spectacle-1.0.0: src/Language/Spectacle/Model/Monad.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
--
-- @since 1.0.0
module Language.Spectacle.Model.Monad
( -- * Model Monad
ModelIO,
-- * Model Transformer
ModelM (ModelM),
unModelM,
runModelM,
-- * Re-exports
module Language.Spectacle.Model.ModelEnv,
module Language.Spectacle.Model.ModelError,
module Language.Spectacle.Model.ModelState,
)
where
import Control.Monad.Except (ExceptT (ExceptT), MonadError, runExceptT)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Reader (MonadReader, ReaderT (ReaderT), runReaderT)
import Control.Monad.Ref (RefM, runRefM)
import Control.Monad.State (MonadState)
import Data.Function ((&))
import Language.Spectacle.Model.ModelEnv
( ModelEnv,
actionInfo,
fairnessOf,
modalityOf,
newModelEnv,
strongFairActions,
unfairActions,
weakFairActions,
)
import Language.Spectacle.Model.ModelError (ModelError)
import Language.Spectacle.Model.ModelState
( ModelState,
enabledActionsAt,
indexNode,
member,
queuedActionsAt,
)
-- ---------------------------------------------------------------------------------------------------------------------
type ModelIO ctx = ModelM ctx IO
newtype ModelM ctx m a = ModelM
{unModelM :: ExceptT (ModelError ctx) (ReaderT ModelEnv (RefM (ModelState ctx) m)) a}
deriving (Functor, Applicative, Monad, MonadIO)
runModelM ::
MonadIO m =>
ModelM ctx m a ->
ModelEnv ->
ModelState ctx ->
m (ModelState ctx, Either (ModelError ctx) a)
runModelM model env st =
unModelM model
& runExceptT
& flip runReaderT env
& flip runRefM st
-- | @since 1.0.0
deriving instance MonadIO m => MonadState (ModelState ctx) (ModelM ctx m)
-- | @since 1.0.0
deriving instance Monad m => MonadReader ModelEnv (ModelM ctx m)
-- | @since 1.0.0
deriving instance Monad m => MonadError (ModelError ctx) (ModelM ctx m)