本文介绍了与ReaderT IO一起使用servant a的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 20:50