
Tom Pledger writes:
By the way, how does the a in a -> b -> IO (b, Bool) work? It looks like it has something to do with the current row. Does doquery have to accommodate any possible substitution for a ?
I fired this off without thinking about it too much, and looking at the prelude type signatures for fold. The list being folded over is implied by the DB query, is accessible through the IO monad. Hence a parameter is not required. It would really be: doquery :: Process -> String -> b -> (b -> IO (b,Bool)) -> IO b
I don't have a preference, but offer this view of the options:
With an exception, "Stop, and return the last b you saw." With a boolean, "Stop, and return this b."
I think I like the behavior where, when the bool in the tuple is true, the b in the tuple is immediately returned from the query. Exceptions would be propagated to the caller of doquery without modification (but with appropriate cleanups). One thing that I am unsure about is whether the column value accessing functions that I specified before stringv :: Process -> CInt -> IO String doublev :: Process -> CInt -> IO Double intv :: Process -> CInt -> IO Int should return actions in the IO monad as above, or instead should be in some other DBQuery monad, that trivially extends the IO monad, but is only valid inside the doquery call. This would have the benefit of restricting the column access functions to inside a query via the type system. I'd also probably use a typeclass to specify a single colv function. ie: class DBCol a where colv :: DBQuery a instance DBCol String where... instance DBCol Double where... doquery :: Process -> String -> b -> (b -> DBQuery (b,Bool)) -> IO b Any comments? Tim