{-# LANGUAGE DerivingVia #-} {- | Module : Iris.App Copyright : (c) 2022 Dmitrii Kovanikov SPDX-License-Identifier : MPL-2.0 Maintainer : Dmitrii Kovanikov Stability : Experimental Portability : Portable The application monad — 'CliApp'. Many functions in __Iris__ are polymorphic over any monad that has the 'MonadReader' constraint. Implement your own application monad as a __newtype__ wrapper around 'CliApp' in the following way. @ __newtype__ App a = App { unApp :: Iris.'CliApp' MyOptions MyEnv a } __deriving newtype__ ( 'Functor' , 'Applicative' , 'Monad' , 'MonadIO' , 'MonadUnliftIO' , 'MonadReader' (Iris.'CliEnv' MyOptions MyEnv) ) @ @since 0.0.0.0 -} module Iris.App ( CliApp (..), runCliApp, runCliAppManually, ) where import Control.Monad.IO.Class (MonadIO) import Control.Monad.IO.Unlift (MonadUnliftIO) import Control.Monad.Reader (MonadReader, ReaderT (..)) import Iris.Env (CliEnv, mkCliEnv) import Iris.Settings (CliEnvSettings) {- | Main monad for your CLI application. The type variables are: * @cmd@: the data type for your CLI arguments * @appEnv@: custom environment for your application (can be just @()@ if you don't need one) * @a@: the value inside the monadic context @since 0.0.0.0 -} newtype CliApp cmd appEnv a = CliApp { unCliApp :: CliEnv cmd appEnv -> IO a } deriving ( Functor -- ^ @since 0.0.0.0 , Applicative -- ^ @since 0.0.0.0 , Monad -- ^ @since 0.0.0.0 , MonadIO -- ^ @since 0.0.0.0 , MonadReader (CliEnv cmd appEnv) -- ^ @since 0.0.0.0 , MonadUnliftIO -- ^ @since 0.0.0.0 ) via ReaderT (CliEnv cmd appEnv) IO {- | Run application with settings. This function is supposed to be used in your @main@ function: @ app :: App () app = ... your main application ... main :: IO () main = 'runCliApp' mySettings (unApp app) @ @since 0.0.0.0 -} runCliApp :: CliEnvSettings cmd appEnv -> CliApp cmd appEnv a -> IO a runCliApp settings cliApp = do cliEnv <- mkCliEnv settings runCliAppManually cliEnv cliApp {- | Run application by constructing 'CliEnv' settings manually. @since 0.0.0.0 -} runCliAppManually :: CliEnv cmd appEnv -> CliApp cmd appEnv a -> IO a runCliAppManually cliEnv (CliApp run) = run cliEnv