typeServeFor site a = (RawUserIdGettersite) => ReaderT (ServiceContext site) (HandlerFor site) a
runServeFor :: ServeFor site a -> (HandlerFor site) a runServeFor service = do let sc = ServiceContext ... runReaderT service sc
serveFor1 :: ServeFor site a serveFor1 = do sc <- ask ....
serveFor2 :: ServeFor site a serveFor1 = do sc <- ask ....
myhandler :: Handler a myhandler = do runServeFor serveFor1 runServeFor serveFor2
提供参数
每个Service都有独立的参数类型,提供的方式又有很多种
方式1:放在ServiceContext
为ServiceContext添加一个参数类型
1 2 3 4 5
dataServiceContext site a = ServiceContext { serviceCtxUserId :: RawUserId site , serviceCtxTime :: LocalTime , serviceData :: a -- 新增参数 }
runServeFor需要添加一个参数
1 2 3 4 5 6 7 8
runServeFor :: form -> ServeFor site a -> (HandlerFor site) a runServeFor form service = do -- 需要提供表单给ServiceContext let sc = ServiceContext { ... serviceData = form } runReaderT service sc
classService param site where typeOutput param action :: param -> ServeFor site (Output param)
newtypeAddUserService = AddUserServiceUserForm newtypeAddUserService = AddGroupServiceGroupForm instanceServiceAddUserServiceAppwhere action :: AddUserService -> ServeFor site () instanceServiceAddGroupServiceAppwhere action :: AddGroupService -> ServeFor site () classServiceRunner site where
runService :: (ServiceRunner site) => Service site -> HandlerFor site result instanceServiceRunnerAppwhere runService service = ServiceContext <$> getRawUserId <*> nowDateTime >>= runReaderT (action service)
使用newtype
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
newtypeService site param result = Service { action :: param -> ServeForsiteresult }
addUserService :: ServiceAppUserForm ()
addGroupService :: ServiceAppGroupForm () classServiceRunner site where
runService :: (Service param result site) => param -> HandlerFor site result instanceServiceRunnerAppwhere runService service = ServiceContext <$> getRawUserId <*> nowDateTime >>= runReaderT (action service)
runServeFor :: ServeFor site param a -> ServiceContext site param -> HandlerFor site a runServeFor (ServeFor service) context = runReaderT service context
在ServeFor中使用HandlerFor需要对HandlerFor提升
1 2 3
instanceMonadHandler (ServeForsiteparam) where typeHandlerSite (ServeForsiteparam) = site liftHandler handler = ServeFor $ lift handler