[Haskell-cafe] Re: Strictness, order of IO operations: NewCGI & HDBC

Tim Smith trangayesi at gmail.com
Fri Oct 20 17:42:17 EDT 2006

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

-- 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.


Thank you,

If you're not part of the solution, you're part of the precipitate.

More information about the Haskell-Cafe mailing list