[Haskell-cafe] Help using CGIT
Ian Lynagh
igloo at earth.li
Wed Aug 22 17:28:28 EDT 2007
On Wed, Aug 22, 2007 at 01:27:00PM -0500, Rich Neswold wrote:
>
> > newtype App a = App (ReaderT Connection (CGIT IO) a)
> > deriving (Monad, MonadIO, MonadReader Connection)
>
> 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 = ?
You have three choices:
1:
Install the unportable (works in GHC, not sure about hugs, not in
anything else TTBOMK) cgi-undecidable package and import
Network.CGI.Undecidable.
instance MonadCGI App where
cgiAddHeader n v = App $ cgiAddHeader n v
cgiGet x = App $ cgiGet x
Here Network.CGI.Undecidable provides the instance for MonadReader. The
nice thing about this one is it'll keep working is you later add a
StateT, say.
2:
Provide an instance for ReaderT and an instance for App that uses it:
instance MonadCGI App where
cgiAddHeader n v = App $ cgiAddHeader n v
cgiGet x = App $ cgiGet x
instance MonadCGI m => MonadCGI (ReaderT c m) where
cgiAddHeader n v = lift $ cgiAddHeader n v
cgiGet x = lift $ cgiGet x
Here the individual bits will keep working if you add a StateT, but you
will also need to add a StateT instance.
3:
Provide a single instance for App that does the whole thing:
instance MonadCGI App where
cgiAddHeader n v = App $ lift $ cgiAddHeader n v
cgiGet x = App $ lift $ cgiGet x
This one you would obviously have to change if you added a StateT.
> 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.
runApp :: App CGIResult -> IO ()
runApp (App a) =
bracket (connect "host" "dbname" "user" "password")
disconnect
(\c -> runCGI (runReaderT a c))
(the above is mostly untested, so it may be wrong in some details).
Thanks
Ian
More information about the Haskell-Cafe
mailing list