packages feed

oplang-0.4.0.0: src/Control/Monad/Comp.hs

module Control.Monad.Comp(CompT(..), runCompT) where

import Control.Applicative(Alternative)
import Control.Monad(MonadPlus)
import Control.Monad.IO.Class(MonadIO)
import Control.Monad.Reader(MonadReader, ReaderT(..))
import Control.Monad.Trans(MonadTrans(..))
import Control.Monad.Trans.Maybe(MaybeT(..))
import Control.Monad.Trans.Writer.CPS(WriterT, runWriterT)
import Control.Monad.Writer.CPS(MonadWriter)
import Data.Text(Text)

import Opts(Opts)

-- The "Compilation" Monad Transformer
newtype CompT m a =
  CompT (ReaderT Opts (MaybeT (WriterT [Text] m)) a)
  deriving newtype
    ( Functor
    , Applicative
    , Alternative
    , Monad
    , MonadPlus
    , MonadReader Opts
    , MonadWriter [Text]
    , MonadIO
    )

instance MonadTrans CompT where
  lift :: Monad m => m a -> CompT m a
  lift = CompT . lift . lift . lift

runCompT :: CompT m a -> Opts -> m (Maybe a, [Text])
runCompT (CompT m) = runWriterT . runMaybeT . runReaderT m