我正在尝试使用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 …Run Code Online (Sandbox Code Playgroud) 在Web,Scotty:连接池作为monad阅读器的问题中,它显示了如何使用在堆栈中ScottyT嵌入Readermonad来访问静态配置(在这种情况下,连接池).
我有一个类似的问题,但更简单 - 或者至少我是这么认为的......
我想添加一个Reader处理程序(即a ActionT),而不是整个应用程序.
我开始从上面的问题修改程序,但我无法弄清楚如何ActionT Text (ReaderT String IO)转换成ActionT Text IO处理程序需要.在摸索并试图使用打字孔希望看到如何构建这个之后我不得不放弃现在并寻求帮助.我真的觉得这应该很简单,但无法弄清楚如何做到这一点.
这是程序,我被卡住的行突出显示:
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.Lazy as T
import Data.Text.Lazy (Text)
import Control.Monad.Reader
import Web.Scotty.Trans
type ActionD = ActionT Text (ReaderT String IO)
main :: IO ()
main = do
scottyT 3000 id id app
-- Application
app :: ScottyT Text IO ()
app = do
get "/foo" $ do …Run Code Online (Sandbox Code Playgroud)