⬑
嵌套Monad Transform的典型App
import Control.Monad.Writer import Control.Monad.State import Control.Monad.Trans
data Model = Model
{ a :: Int
, b :: Int
} deriving (Show)
newtype App a = App
{ runApp :: StateT Model (WriterT [String] IO) a
} deriving
( Functor
, Applicative
, Monad
, MonadState Model
, MonadWriter [String]
, MonadIO
)
execApp :: Model -> App a -> IO a
execApp model app = do
((ret, newState), log) <- runWriterT (runStateT (runApp app) model)
putStrLn $ show log
putStrLn $ show newState
return ret
appMain :: App String
appMain = do
tell ["init"]
put Model {a = 1, b = 2}
liftIO $ putStrLn "init"
input <- liftIO $ getLine
return input
main = do
input <- execApp (Model {a = -1, b = -2}) appMain
putStrLn input
return ()