
John, Café patrons, Thanks a lot for your detailed reply. Sorry it's taken me so long to respond, but I wanted to test some things out first. I've spent many a dark hour thinking about this, and now come crawling back to the café for some help. The folks on #haskell helped some, but eventually gave up and asked me to try here instead. I can make this work with bracket (as you suggested in your second reply), if I want to use the database handle in the IO monad. I.e., if I want the meat of my program to be something like: -- See working program at: http://paste.lisp.org/display/28273 proc :: Connection -> IO a proc dbh = ... But I want to use the database handle inside the CGI monad, so I can query the database, process the CGI results, and perhaps return HTML output or redirect to a different URL, etc. I can do that if I avoid bracket, and use deepSeq to force the results (as you suggested in your first reply - although 'evaluate' and 'seq' weren't strong enough): -- See working program at: http://paste.lisp.org/display/28273#4 ... dbResult <- DB.handleSqlError action dbResult `deepSeq` return dbResult But I can't combine those two techniques. I tried breaking it down by writing: -- See code & compiler errors: http://paste.lisp.org/display/28273#4 -- Copied from GHC's definition of bracket myBracket :: IO a -> (a -> IO b) -> (a -> CGI.CGI c) -> CGI.CGI c myBracket acquire destroy use = I can't manage to resolve the type conflicts. It was suggested that I should just forget about calling disconnect. If the HDBC semantics are lazy IO, then HDBC should be responsible for closing the connection when it's no longer needed, they say. Practically, I guess it will work. But theoretically it bugs the hell out of me that I can't figure out how to combine these monads properly. I've been reading through All About Monads and other resources, and have the School of Expression book as well, but haven't gotten it sorted. It was also suggested that I might use MonadError instead of bracket. I haven't explored that yet. Has anyone found out how to lift bracket into another monad? In order to hopefully make it easier for someone to respond, I've made a test program which has the same structure, but uses StateT instead of CGI, and simple IO instead of HDBC. A solution which applies to this test program should apply directly to my CGI program as well. http://www.magnesium.net/~thim/tmp/transbracket.hs Thank you, Tim -- If you're not part of the solution, you're part of the precipitate.