我正在尝试使用额外的ClientM
参数来扩展servant的Token
monad,我将用它来调用REST资源。
type TClient a = ReaderT Token ClientM a
然后我为服务方模式匹配定义了以下内容
get :: Token -> ClientM Text
post :: Token -> Int -> ClientM Text
get :<|> post = client (Proxy :: Proxy MyAPI)
现在我的扩展客户端开始玩了。这就是我使用它的方式:
getT :: TClient Text
getT = undefined -- implementation to extract token and call 'get'
postT :: Int -> TClient Text
portT = undefined -- implementation to extract token and call 'post'
queries :: TClient Text
queries = do
text1 <- postT 5
text2 <- getT
return (text1 ++ text2)
--| runReaderT and then runClientM
runTClient :: Token -> TClient a -> ClientEnv -> IO (Either ServantError a)
runTClient token tcm env = runClientM (runReaderT tcm token) env
问题是如何更好地实施getT
和postT
功能。
我将发布我当前的解决方案,但希望更有经验的haskellers在这里建议更好的
答案 0 :(得分:1)
以下示例在页面底部使用IO Control Monad Reader我必须实现提升ReaderT
的功能
liftReaderT :: m a -> ReaderT r m a
liftReaderT m = ReaderT (const m)
那么我可以像这样详细实现:
getT :: TClient Text
getT = do
t <- ask
liftReaderT $ get t
答案 1 :(得分:1)
ReaderT r
是MonadTrans
的一个实例,因此您只需使用lift :: (MonadTrans t, Monad m) => m a -> t m a
即可。专门针对有问题的类型,即lift :: ClientM a -> ReaderT Token ClientM a
。
getT :: Int -> TClient Text
getT = lift . get
postT :: Int -> TClient Text
postT = lift . post