Web, Scotty: connection pool as monad reader问题中,展示了如何使用ScottyTReader monad嵌入堆栈中以访问静态配置(在这种情况下为连接池)。

我有一个类似的问题,但是更简单–或者至少我是这么认为的…

我想将Reader添加到单个处理程序(即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

最佳答案

如果要在单独的阅读器中运行每个操作,则根本不需要更复杂的Scotty.Trans接口(interface)。您可以以其他方式构建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

关于haskell - 适用于每个处理器读取器的Scotty Monad变压器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28361505/

10-15 11:20