本文介绍了在ScottyT中使用ReaderT转换器(vs ActionT)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我试图使用ReaderT monad变压器方法通过基于Scotty的应用程序进行线程配置,并且遇到麻烦。在定义路由时(因为它们中的一些取决于配置)以及处理实际请求时,我必须使用配置。 后者在ActionT中工作得很好,但无论我尝试什么,我都无法在ScottyT中获得正确的类型。 以下是我从Scotty GitHub存储库的ReaderT样本编译的最小示例: { - #LANGUAGE GeneralizedNewtypeDivingiving# - } { - #LANGUAGE OverloadedStrings# - } module主要在哪里 导入Control.Applicative 导入Control.Monad.Reader(MonadIO,MonadReader,ReaderT,请求,提升,runReaderT)导入Data.Default.Class(def) import Data.Text.Lazy(Text,pack) import Prelude import Web.Scotty.Trans(ScottyT,get,scottyOptsT,text,capture) 数据Config = Config {environment :: String }派生(Eq,Read,Show) newtype ConfigM a = ConfigM {runConfigM :: ReaderT Config IO a } d eriving(Applicative,Functor,Monad,MonadIO,MonadReader Config) application :: ScottyT Text ConfigM() application = do get/$ do e < - lift $请求环境文本$ pack $ show e 路径< - lift $请求环境 get(捕获路径)$ do text $ pack $Hello,custom path $ b $ main :: IO() main = scottyOptsT def runIO application其中 runIO :: ConfigM a - > IO a runIO m = runReaderT(runConfigM m)config config :: Config config = Config {environment =Development} 我得到的错误是: •没有使用'lift'产生的(Control.Monad.Trans.Class.MonadTrans (ScottyT Text))的实例•在do块的路径中:path< - lift $ asks environment 我已经通过代码描述了ScottyT类型的代码,实际上似乎没有为它定义的MonadTrans实例。然而,我并不觉得自己有足够的法力和Haskell经验来找到解决办法,并希望得到任何帮助! b 谢谢! 解决方案有了集体意识,我们都能找到目前可行的解决方案问题。 ScottyT类型是一个monad变换器,其后是 https://github.com/scotty-web/scotty/pull/167 被合并,因此目前没有办法以这种方式使用它。有一个公关 https://github.com/scotty-web/scotty/pull/ 181 旨在将这个特性带回来,但据我所知,它从来没有合并过。 因为它不是一个monad变压器,所以我们只能包装它 { - #LANGUAGE GeneralizedNewtypeDeriving# - } { - #LANGUAGE OverloadedStrings# - } 模块Main其中 导入Control.Applicative 导入Control.Monad.Reader(MonadIO,MonadReader,ReaderT,请求,提升,runReaderT) import Data.Default .class(def) import Data.Text.Lazy(Text,pack) import Prelude import Web.Scotty.Trans(ScottyT,get,scottyOptsT,text,capture) data Config = Config {environment :: String }派生(Eq,Read,Show) newtype ConfigM a = ConfigM {runConfigM :: ReaderT配置IO a }派生(Applicative,Functor,Monad,MonadIO,MonadRead er配置) application :: ConfigM(ScottyT Text ConfigM()) application = do path< - 询问环境 返回$ get/$ do e< - lift $请求环境文本$ pack $ show e get(捕获路径)$ text $ pack $Hello,custom path runIO :: Config - >配置a - > IO a runIO cm = runReaderT(runConfigM m)c main :: IO() main = do let config = Config {environment =/ path } app scottyOptsT def(runIO config)app 感谢大家帮助我,希望这可以帮助像我这样的另一个流浪Scotty:)。 I'm trying to thread configuration through my Scotty based application using ReaderT monad transformer approach, and having trouble doing so. I have to use configuration both when defining routes (as some of them depend on the config) and when handling actual requests.The latter works just fine in the ActionT, but no matter what I try I just can't get the types right in ScottyT.Here's the minimal example I compiled from the ReaderT sample from Scotty GitHub repository:{-# LANGUAGE GeneralizedNewtypeDeriving #-}{-# LANGUAGE OverloadedStrings #-}module Main whereimport Control.Applicativeimport Control.Monad.Reader (MonadIO, MonadReader, ReaderT, asks, lift, runReaderT)import Data.Default.Class (def)import Data.Text.Lazy (Text, pack)import Preludeimport Web.Scotty.Trans (ScottyT, get, scottyOptsT, text, capture)data Config = Config { environment :: String } deriving (Eq, Read, Show)newtype ConfigM a = ConfigM { runConfigM :: ReaderT Config IO a } deriving (Applicative, Functor, Monad, MonadIO, MonadReader Config)application :: ScottyT Text ConfigM ()application = do get "/" $ do e <- lift $ asks environment text $ pack $ show e path <- lift $ asks environment get (capture path) $ do text $ pack $ "Hello, custom path"main :: IO ()main = scottyOptsT def runIO application where runIO :: ConfigM a -> IO a runIO m = runReaderT (runConfigM m) config config :: Config config = Config { environment = "Development" }The error I'm getting is:• No instance for (Control.Monad.Trans.Class.MonadTrans (ScottyT Text)) arising from a use of ‘lift’• In a stmt of a 'do' block: path <- lift $ asks environmentI've looked through the code where ScottyT type is outlined, and indeed there doesn't seem to be an instance of MonadTrans defined for it. However, I don't feel I have enough both mana and Haskell experience to find a way out of it and would appreciate any help!Thank you! 解决方案 With a collective mind we all came to a currently viable solution to the problem.ScottyT type cased to be a monad transformer with after https://github.com/scotty-web/scotty/pull/167 got merged, therefore there's currently no way of using it this way. There was a PR https://github.com/scotty-web/scotty/pull/181 aimed at bringing that feature back, but as far as I understood it has never got merged.Since it's not a monad transformer we can only wrap it again:{-# LANGUAGE GeneralizedNewtypeDeriving #-}{-# LANGUAGE OverloadedStrings #-}module Main whereimport Control.Applicativeimport Control.Monad.Reader (MonadIO, MonadReader, ReaderT, asks, lift, runReaderT)import Data.Default.Class (def)import Data.Text.Lazy (Text, pack)import Preludeimport Web.Scotty.Trans (ScottyT, get, scottyOptsT, text, capture)data Config = Config { environment :: String } deriving (Eq, Read, Show)newtype ConfigM a = ConfigM { runConfigM :: ReaderT Config IO a } deriving (Applicative, Functor, Monad, MonadIO, MonadReader Config)application :: ConfigM (ScottyT Text ConfigM ())application = do path <- asks environment return $ get "/" $ do e <- lift $ asks environment text $ pack $ show e get (capture path) $ text $ pack $ "Hello, custom path"runIO :: Config -> ConfigM a -> IO arunIO c m = runReaderT (runConfigM m) cmain :: IO ()main = do let config = Config { environment = "/path" } app <- runIO config application scottyOptsT def (runIO config) appThanks everyone for helping me out, and hopefully this helps another wandering Scotty like me :). 这篇关于在ScottyT中使用ReaderT转换器(vs ActionT)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-22 23:23