我想将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) ()
答案 0 :(得分:1)
您必须将您提供的参数id
更改为分别具有forall a. m a -> n a
和m Response -> IO Response
类型的参数。为什么?我不知道,但我发现here的示例显示有人运行它类似于
main = do
let config = Config "Hello, world"
runner = flip runReaderT config
scottyT 3000 runner runner routes
我已经测试了它,至少它可以工作。我不知道这是否是最佳实践。如果某人有更好的方法,请随意发布。