haskell - 如何让 ReaderT 与另一个 monad 转换器一起工作?

标签 haskell monads monad-transformers

我想将 ReaderT 嵌入到另一个 monad 转换器中。我该怎么做呢?下面的示例使用 Scotty但我认为这与任何其他 monad 都是一样的。

{-# LANGUAGE OverloadedStrings #-}

import qualified Web.Scotty
import Web.Scotty.Trans

import Data.Text.Lazy
import Control.Monad.IO.Class (liftIO)

import Control.Monad.Trans.Reader
import Control.Monad.Trans

data Config = Config Text

main :: IO ()
main = do
    let config = Config "Hello World"
    -- how to I make this line work?
    scottyT 3000 id id routes

routes :: ScottyT Text (ReaderT Config IO) ()
routes = do
    get "/" info

info :: ActionT Text (ReaderT Config IO) ()
info = do
    -- this part seems like it works!
    Config message <- lift ask
    text $ "Info: " `append` message

scottyT 3000 id id routes 行出现此错误,因为 scottyT 需要 ScottyT Text IO ()。我如何使这项工作?以下是当前的错误:

Server.hs: line 24, column 24:
  Couldn't match type `ReaderT Config IO' with `IO'
    Expected type: ScottyT Text IO ()
      Actual type: ScottyT Text (ReaderT Config IO) ()

最佳答案

您必须将作为 id 提供的参数更改为类型为 forall a 的参数。分别为 m a -> n am Response -> IO Response。为什么?我不知道,但我找到的例子 here显示有人在运行它类似于

main = do
    let config = Config "Hello, world"
        runner = flip runReaderT config
    scottyT 3000 runner runner routes

我已经测试过了,它至少可以工作。我不知道这是否是最佳实践。如果有人有更好的方法,请随时发布。

关于haskell - 如何让 ReaderT 与另一个 monad 转换器一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26065765/

相关文章:

haskell - 生成真值表

haskell - 允许相等值位于自平衡二叉树两侧的缺点?

Haskell 断言一种类型将与另一种类型匹配

haskell - mtl、transformers、monads-fd、monadLib 和选择悖论

scala - 如何将 scalaz.EitherT.fromEither 应用于 scalaz.\/?

scala - 通过 Scala 中的解析器线程化额外状态

haskell - 在固定时间内计算尽可能多的列表

performance - StateT over Reader 和 ReaderT over State 之间有什么显着区别吗?

scala - Scala 中的 Monad 变形金刚

performance - 为什么不能应用遍历数组? (或者是吗?)