typeDb site = ReaderTConnection (HandlerForsite) typeService site = ReaderTServiceContext (HandlerForsite) -- 嵌套 typeDbService site = ReaderTConnection (Servicesite)
runDB :: Db site a -> HandlerForApp a runDB = ...
runDBService :: DbService site a -> Service site a runDBService dbService = do -- 解包最外层,得到Service lift $ runDB $ runInnerService dbService where -- 转换ReaderT的Monad参数,等同下方 -- runInnerService :: ReaderT Connection (Service site) a -> ReaderT Connection (HandlerFor site) a runInnerService :: DbService site a -> Db site a runInnerService dbService = hoistReaderT runService dbService
-- 因为 ReaderT r m a = ReaderT { runReaderT :: r -> m a } -- 所以 f :: r -> ma hoistReaderT :: (m a -> n a) -> ReaderT r m a -> ReaderT r n a hoistReaderT nat (ReaderT f) = ReaderT (nat . f)