问题描述
我为我的JSON API使用了 servant
库。我需要一些帮助来获得 ServerT MyAPI(ReaderT a IO)
monad堆栈的工作方式。
下面是一个使用 ReaderT
的例子,但没有与servant整合:
- 此代码有效
类型TestAPI =
a:>获取'[JSON]字符串
:< |> b:>获取'[JSON]字符串
test2 :: EitherT ServantErr IO字符串
test2 =返回asdf
testServer :: Int - > Server TestAPI
testServer code = test:< |> test2
其中
test :: EitherT ServantErr IO字符串
测试= liftIO $ runReaderT(giveMeAMessage)代码
- 这是人为设计的。在我的真实应用程序中,我想使用Reader进行数据库连接。
giveMeAMessage :: ReaderT Int IO String
giveMeAMessage = do
code< - ask
name< - liftIO $ getProgName
return $ show code<>名称
所以,现在我想让它与ServerT一起工作,按照。
- 此代码不会编译
testServerT :: ServerT TestAPI(ReaderT Int IO)
testServerT = test :其中; |> test
where
test :: EitherT ServantErr(ReaderT Int IO)String
test = lift $ giveMeAMessage
testServer':: Int - > Server TestAPI
testServer'code = enter(Nat $ liftIO。(`runReaderT` code))testServerT
我得到以下错误:
server / Serials / Route / Test.hs:43:15:
无法匹配类型'EitherT ServantErr(ReaderT Int IO)字符串'
'与'ReaderT Int IO [Char]'
预期类型:ServerT TestAPI(ReaderT Int IO)
实际类型: EitherT ServantErr(ReaderT Int IO)字符串
:< |> EitherT ServantErr(ReaderT Int IO)字符串
在表达式中:test:< |>测试
在'testServerT'的等式中:
testServerT
= test:< |>测试
其中
test :: EitherT ServantErr(ReaderT Int IO)字符串
测试=提升$ giveMeAMessage
失败,模块加载:无。
如何摆脱错误?
后续问题:我通常理解monad变形金刚,但我迷路了。我应该学习哪些主题或链接,以便足以回答我自己的问题?
您几乎在那里,测试应该是:
test :: ReaderT Int IO String
test = giveMeAMessage
至于你的其他问题,我现在没有时间回答,但是我们的仆人开发人员可能应该让它更容易或更好地记录。
请你通读一下哪个部分让你感到困惑,然后问具体问题?
I'm using the servant
library for my JSON API. I need some help to get a ServerT MyAPI (ReaderT a IO)
monad stack working.
Here's an example using ReaderT
, but without integrating it with servant:
-- this code works
type TestAPI =
"a" :> Get '[JSON] String
:<|> "b" :> Get '[JSON] String
test2 :: EitherT ServantErr IO String
test2 = return "asdf"
testServer :: Int -> Server TestAPI
testServer code = test :<|> test2
where
test :: EitherT ServantErr IO String
test = liftIO $ runReaderT (giveMeAMessage) code
-- this is contrived. In my real application I want to use a Reader for the database connection.
giveMeAMessage :: ReaderT Int IO String
giveMeAMessage = do
code <- ask
name <- liftIO $ getProgName
return $ show code <> name
So, now I would like to get it working with ServerT, following the example in this article.
-- this code doesn't compile
testServerT :: ServerT TestAPI (ReaderT Int IO)
testServerT = test :<|> test
where
test :: EitherT ServantErr (ReaderT Int IO) String
test = lift $ giveMeAMessage
testServer' :: Int -> Server TestAPI
testServer' code = enter (Nat $ liftIO . (`runReaderT` code)) testServerT
I get the following error:
server/Serials/Route/Test.hs:43:15:
Couldn't match type ‘EitherT ServantErr (ReaderT Int IO) String’
with ‘ReaderT Int IO [Char]’
Expected type: ServerT TestAPI (ReaderT Int IO)
Actual type: EitherT ServantErr (ReaderT Int IO) String
:<|> EitherT ServantErr (ReaderT Int IO) String
In the expression: test :<|> test
In an equation for ‘testServerT’:
testServerT
= test :<|> test
where
test :: EitherT ServantErr (ReaderT Int IO) String
test = lift $ giveMeAMessage
Failed, modules loaded: none.
How can I get rid of the error?
Followup question: I understand monad transformers generally, but I'm lost. What topics or links should I study to know enough to answer my own question?
You were almost there, test should be:
test :: ReaderT Int IO String
test = giveMeAMessage
As for your other questions, I don't have time to answer just now but us servant developers should probably make it easier or better documented.
Could you please read through the source for whichever part confuses you, and then ask specific questions?
这篇关于与ReaderT IO一起使用servant a的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!