stu*_*ith 6 haskell monad-transformers scotty
我正在尝试使用Scotty来构建一个非常简单的API.我想扩展Scotty monad,以便我的路由处理程序操作能够访问一个不变的环境.我相信这样做的方法是Reader在堆栈中添加一个monad.现在我只想传递一些Text数据.
我把Scotty monads扩展如下:
type BrandyScottyM = ScottyT TL.Text (ReaderT T.Text IO)
type BrandyActionM = ActionT TL.Text (ReaderT T.Text IO)
Run Code Online (Sandbox Code Playgroud)
https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Core.hs
所以我的第一个问题是,这是正确的方法吗?
我已经成功地改变了我的路由处理程序的类型,但我无法弄清楚如何使用这个堆栈启动Scotty.我尝试过以下方法:
runScotty :: Port -> Text -> BrandyScottyM () -> IO ()
runScotty port file = T.scottyT port ((\f -> runReader f file)) id
Run Code Online (Sandbox Code Playgroud)
https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Main.hs
但我得到错误:
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
Run Code Online (Sandbox Code Playgroud)
所以我的第二个问题是,如何使用不同的monad堆栈启动Scotty?这是我第一次尝试使用monad变换器,我似乎无可救药地丢失了.
dup*_*ode 10
你的方法看起来没问题.类型错误是因为你应该使用runReaderT而不是runReader(runReader仅当你使用时Reader,它只使用它下面ReaderT的虚拟Identitymonad).