本文介绍了我如何将阅读器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中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!