我正在嘗試使用Scotty來構建一個非常簡單的API。我想擴展Scotty monads,使我的路由處理器操作能夠訪問不變的環境。我相信這樣做的方法是將一個Reader
monad添加到堆棧。現在我只想通過一些Text
數據。我如何將讀者monad添加到Scotty的monad中?
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
所以我的第一個問題是,這是正確的做法:
我如下擴展斯科蒂單子?
我已經成功地更改了我的路由處理程序的類型,但我無法解決如何使用此堆棧來啓動Scotty。我已經嘗試以下操作:
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
但我得到的錯誤:
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
所以我的第二個問題是,我該如何推出斯科蒂用不同的單子棧?這是我第一次嘗試使用monad變形金剛,並且我似乎無望地迷路了。
啊哈太棒了,讓我在正確的路線。我還必須在應用程序和操作級別都創建'Reader',所以最終的調用是:''.scottyT port(\'runReaderT \'file)(\'runReaderT \'file)' – stusmith