本文介绍了我如何将阅读器monad添加到Scotty的monad中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Scotty来构建一个非常简单的API。我想扩展Scotty monads,使我的路由处理器操作能够访问不变的环境。我相信这样做的方法是将一个 Reader monad添加到堆栈中。现在我只想传递一些 Text 数据。



我已经扩展了Scotty monads,如下所示:

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



所以我的第一个问题是,这是正确的方法吗?



我成功地改变了我的路由处理程序的类型, t研究如何使用这个堆栈来启动Scotty。我尝试了以下方法:

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



但我得到错误:

 无法与`Data.Functor.Identity.Identity'类型'IO'匹配
期望类型:读者文本(IO a)
实际类型:ReaderT文本IO a
在`runReader'的第一个参数中,即`f'
在表达式:runReader f file
'T.scottyT'的第二个参数中,即
`((\ f - > runReader f file))'
/home/stu/git/Brandy/src/Main.hs:第36行,第65列:
无法匹配类型` ReaderT Text IO Network.Wai.Internal.Response'
with`IO Network.Wai.Internal.Response'
预期类型:ReaderT Text I O Network.Wai.Internal.Response
- > IO Network.Wai.Internal.Response
实际类型:ReaderT Text IO Network.Wai.Internal.Response
- > ReaderT Text IO Network.Wai.Internal.Response
在`T.scottyT'的第三个参数中,即`id'
在表达式中:T.scottyT port((\ f - > runReader f文件))id
在'runScotty'公式中:
runScotty port file = T.scottyT port((\ f - > runReader f file))id

所以我的第二个问题是,我如何使用不同的monad堆栈来启动Scotty?这是我第一次尝试使用monad变形金刚,并且我似乎无望地迷了路。 解决方案

您的方法看起来不错。类型错误是因为您应该使用 runReaderT 而不是 runReader runReader 仅适用于使用 Reader ,这是 ReaderT ,只有身份 monad下面)。


I'm trying to use Scotty to build a very simple API. I'd like to extend the Scotty monads such that my route handler actions are able to access an unchanging environment. I believe the way to do this would be to add a Reader monad to the stack. For now I just want to pass some Text data around.

I've extended the Scotty monads as follows:

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

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. 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

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? This is my first attempt at using monad transformers and I seem to be hopelessly lost.

解决方案

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).

这篇关于我如何将阅读器monad添加到Scotty的monad中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 19:44