简体   繁体   English

如何将Reader monad添加到Scotty的monad?

[英]How do I add the Reader monad to Scotty's monad?

I'm trying to use Scotty to build a very simple API. 我正在尝试使用Scotty来构建一个非常简单的API。 I'd like to extend the Scotty monads such that my route handler actions are able to access an unchanging environment. 我想扩展Scotty monad,以便我的路由处理程序操作能够访问一个不变的环境。 I believe the way to do this would be to add a Reader monad to the stack. 我相信这样做的方法是将一个Reader monad添加到堆栈中。 For now I just want to pass some Text data around. 现在我只想传递一些Text数据。

I've extended the Scotty monads as follows: 我把Scotty monads扩展如下:

type BrandyScottyM = ScottyT TL.Text (ReaderT T.Text IO)
type BrandyActionM = ActionT TL.Text (ReaderT T.Text IO)

https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Core.hs https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Core.hs

So my first question is, is this the correct approach? 所以我的第一个问题是,这是正确的方法吗?

I've successfully changed the types of my route handlers, but I can't work out how to launch Scotty using this stack. 我已经成功地改变了我的路由处理程序的类型,但我无法弄清楚如何使用这个堆栈启动Scotty。 I've attempted the following: 我尝试过以下方法:

runScotty :: Port -> Text -> BrandyScottyM () -> IO ()
runScotty port file = T.scottyT port ((\f -> runReader f file)) id

https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Main.hs https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Main.hs

But I get the error: 但我得到错误:

  Couldn't match type `IO' with `Data.Functor.Identity.Identity'
    Expected type: Reader Text (IO a)
      Actual type: ReaderT Text IO a
    In the first argument of `runReader', namely `f'
    In the expression: runReader f file
    In the second argument of `T.scottyT', namely
      `((\ f -> runReader f file))'
/home/stu/git/Brandy/src/Main.hs: line 36, column 65:
  Couldn't match type `ReaderT Text IO Network.Wai.Internal.Response'
                  with `IO Network.Wai.Internal.Response'
    Expected type: ReaderT Text IO Network.Wai.Internal.Response
                   -> IO Network.Wai.Internal.Response
      Actual type: ReaderT Text IO Network.Wai.Internal.Response
                   -> ReaderT Text IO Network.Wai.Internal.Response
    In the third argument of `T.scottyT', namely `id'
    In the expression: T.scottyT port ((\ f -> runReader f file)) id
    In an equation for `runScotty':
        runScotty port file = T.scottyT port ((\ f -> runReader f file)) id

So my second question is, how do I launch Scotty with a different monad stack? 所以我的第二个问题是,如何使用不同的monad堆栈启动Scotty? This is my first attempt at using monad transformers and I seem to be hopelessly lost. 这是我第一次尝试使用monad变换器,我似乎无可救药地丢失了。

Your approach looks okay. 你的方法看起来没问题。 The type error is because you should use runReaderT rather than runReader ( runReader is only for when you use Reader , which is ReaderT with just the dummy Identity monad below it). 类型错误是因为你应该使用runReaderT而不是runReaderrunReader仅适用于你使用Reader ,它是ReaderT ,下面只有虚拟Identity monad)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM