I would like to embed ReaderT
into another monad transformer. How do I do this? The example below uses Scotty
but I think it would be the same with any other 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
This errors on the line scottyT 3000 id id routes
, because scottyT
expects a ScottyT Text IO ()
. How do I make this work? Here are the current errors:
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) ()
flip runReaderT config $ scottyT 3000 id (flip runReaderT config) routes
. I don't think it's correct consideringrunReaderT
is needed twice, but I don't know enough about scotty to know why thescottyT
function requires that argument – bheklilrReaderT Config (ScottyT Text IO) ()
? – felix-ekuget
function has the type(ScottyError e, MonadIO m) => RoutePattern -> ActionT e m () -> ScottyT e m ()
, instead of the more general(ScottyError e, MonadIO m, MonadAction a, MonadScotty s) => RoutePattern -> a e m () -> s e m ()
– bheklilrScotty
stuff without lifting. – Sean Clark Hess