
Hello! I've been having a tough time trying to use the CGI monad transformer (CGIT). Hopefully someone can show me my misstep(s). I have a CGI script that's evolving. Early on, it needed a single database access. Now it's doing two accesses (and it looks like I'll be adding more.) Rather than making a connection for each access, the script needs to connect once. To do this, I want to combine the CGI monad with the Reader monad. This version compiles cleanly:
module AppMonad (App (..), runApp) where
import Control.Exception (bracket) import Control.Monad.Reader import Network.CGI.Monad import Network.CGI.Protocol import System.IO (stdin, stdout) import Database.HSQL.PostgreSQL
newtype App a = App (ReaderT Connection (CGIT IO) a) deriving (Monad, MonadIO, MonadReader Connection)
runApp :: App CGIResult -> IO () runApp (App a) = bracket (connect "host" "dbname" "user" "password") disconnect (\c -> do { env <- getCGIVars ; hRunCGI env stdin stdout (runCGIT (runReaderT a c)) ; return () } )
Unfortunately, when another module tries to actually use the monad, I get warnings about "No instance for (MonadCGI App)". I tried making an instance:
instance MonadCGI App where cgiAddHeader = ? cgiGet = ?
But I don't know how to define these functions. I tried various 'lift'ing combinations, but couldn't come up with a solution that would compile. I'm also disappointed that I had to break apart 'runCGI' (by cut-and-pasting its source) because I couldn't make it believe my monad looked enough like MonadCGI. My previous experiment with monad transformers was successful. It didn't use CGIT, however, so the 'run*' functions were simpler. Does anyone have an example of using CGIT (I didn't find any from Google)? Shouldn't I be able to use 'runCGI' with my monad? CGIT users shouldn't be required to re-implement 'runCGI", right? Any help or ideas is appreciated! -- Rich JID: rich@neswold.homeunix.net AIM: rnezzy