每个处理程序读者的Scotty monad变换器

bet*_*eta 5 haskell monad-transformers scotty

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
    h <- handler              -- ?
    runReaderT h "foo"        -- ?
--get "/bar" $ do
--  h <- handler
--  runReaderT h "bar"

-- Route action handler
handler ::  ActionD ()
handler = do
  config <- lift ask
  html $ T.pack $ show config
Run Code Online (Sandbox Code Playgroud)

sha*_*ang 5

如果您想在单独的阅读器中运行每个操作,则根本不需要更复杂的Scotty.Trans界面。你可以用相反的方式构建你的 monad 堆栈,ReaderT在顶部。

import qualified Data.Text.Lazy as T
import           Control.Monad.Reader
import           Web.Scotty

type ActionD = ReaderT String ActionM

main :: IO ()
main = do
  scotty 3000 app

-- Application
app ::  ScottyM ()
app = do
  get "/foo" $ do
    runReaderT handler "foo"

-- Route action handler
handler ::  ActionD ()
handler = do
  config <- ask
  lift $ html $ T.pack $ show config
Run Code Online (Sandbox Code Playgroud)