Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将基于ReaderT的客户端包装器与服务客户端一起使用_Haskell_Monad Transformers_Servant - Fatal编程技术网

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

t
ReaderT 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'匹配。