iris-0.1.0.0: src/Iris/App.hs
{-# LANGUAGE DerivingVia #-}
{- |
Module : Iris.App
Copyright : (c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer : Dmitrii Kovanikov <kovanikov@gmail.com>
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