1

我正在尝试使用我将用来调用 REST 资源的ClientM附加参数来扩展仆人的 monad 。Token

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可以提出更好的解决方案

4

2 回答 2

1

以下示例在页面底部的 IO控制 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
于 2017-01-10T22:57:34.877 回答
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
于 2017-01-11T00:49:22.880 回答