Haskell 将基于ReaderT的客户端包装器与服务客户端一起使用
我正在尝试使用额外的Haskell 将基于ReaderT的客户端包装器与服务客户端一起使用,haskell,monad-transformers,servant,Haskell,Monad Transformers,Servant,我正在尝试使用额外的令牌参数扩展servant的ClientMmonad,我将使用该参数调用REST资源 type TClient a = ReaderT Token ClientM a 然后我为服务模式匹配定义了以下内容 get :: Token -> ClientM Text post :: Token -> Int -> ClientM Text get :<|> post = client (Proxy :: Proxy MyAPI) get::Toke
令牌
参数扩展servant的ClientM
monad,我将使用该参数调用REST资源
type TClient a = ReaderT Token ClientM a
然后我为服务模式匹配定义了以下内容
get :: Token -> ClientM Text
post :: Token -> Int -> ClientM Text
get :<|> post = client (Proxy :: Proxy MyAPI)
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::TClient Text
getT=undefined——提取令牌并调用“get”的实现
postT::Int->TClient Text
portT=undefined——提取令牌并调用“post”的实现
查询::TClient文本
查询=do
text 1客户端NV->IO(服务错误或a)
runTClient令牌tcm env=runClientM(runReaderT tcm令牌)env
问题是如何更好地实现getT
和postT
函数
我将发布我当前的解决方案,但希望这里更有经验的Haskeller能够推荐更好的解决方案下面的例子中,IO位于页面底部,我必须实现提升
ReaderT的功能
liftReaderT :: m a -> ReaderT r m a
liftReaderT m = ReaderT (const m)
这样我就可以有这样的详细实现:
getT :: TClient Text
getT = do
t <- ask
liftReaderT $ get t
getT::TClient Text
getT=do
tReaderT r
是的一个实例,因此您可以使用lift::(MonadTrans t,Monad m)=>ma->tma
。专门针对所讨论的类型,即lift::ClientM a->ReaderT-Token-ClientM a
getT :: Int -> TClient Text
getT = lift . get
postT :: Int -> TClient Text
postT = lift . post
谢谢你的回答!只执行lift get
我得到的无法将预期类型“ClientM Text”与实际类型“Token->ClientM Text”匹配,因此我必须执行ask>=\t->lift$get t
。@klapvisor我的错误,应该是lift。获取
。我将修复get::Token->ClientM Text
的答案,我必须在getT
中读取Token
,并将其传递给get
。此时进行提升。get
我得到的无法将类型'Token->t0 ClientM Text'与'ReaderT Token ClientM Text'匹配。