| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
Control.Monad.Trans.Compose.Stack
Description
This module gives an alternative interface to build and run monad transformer stacks.
Using this approach is supposed to improve error messages and reduce errors, such as forgetting
to add TransparentT at the bottom of the stack.
StackT
StackT is a more ergonomic way to define a monad transformer stack.
type family StackT (ts :: Stack) = (t :: (Type -> Type) -> Type -> Type) | t -> ts where ... Source #
An isomorphism between a Stack and the corresponding monad transformer, which can be built
using ComposeT.
An additional TransparentT will automatically be used at the bottom of the stack.
You only have to worry about the semantically relevant transformers.
runStackT and RunStackT
Monad transformer stacks, that only consist of IdentityT and
ReaderT, can be run with runStackT.
If your transformer stack contains monadic state StT, you will have to use runComposeT or ./>!
You can still use StackT for the type definition.
data RunStackT :: Stack -> (Type -> Type) -> Type -> Type where Source #
Stack
type data Stack where Source #
A data kind representing a monad transformer stack.
This is basically a type-level list of monad transformers.
Examples
Feel free to compare these examples to the ones in Control.Monad.Trans.Compose.
Example 1: Build a transformer stack
Apply the type family StackT to a type of kind Stack and generate a monad transformer stack built with ComposeT.
type AppStack =NilT:.|>ReaderTBool:.|>CustomT:.|>ReaderTCharnewtype AppT m a = AppT { unAppT :: StackT AppStack m a } deriving newtype (Functor,Applicative,Monad) deriving newtype (MonadTrans,MonadTransControl,MonadTransControlIdentity) deriving newtype MonadCustom deriving newtype (MonadReaderBool)
Example 2: Run a transformer stack
Use runStackT and supply it with a RunStackT argument.
runAppT :: AppT m a -> m a runAppT appTma =runStackTrunAppStackT $ unAppT appTma where runAppStackT =RunNilT:..>(\ tma ->runReaderTtmaTrue):..>runCustomT:..>runReaderT' runReaderT' ::MonadReaderBoolm =>ReaderTCharm a -> m a runReaderT' tma = do bool <-asklet char = if bool then 'Y' else 'N'runReaderTtma char