
Hi folks, I set out to perform a (seemingly) simple experiment last night. I thought I'd try to get used to the HSQL library by writing a little app that would take an SQL query on the command line, run it, and print the results. So far, this seems to be impossible. I'd like to know if there's a way around this problem, or if this is actually insurmountable (short of generating and compiling new Haskell programs for each query). The HSQL library works quite well for queries whose types you know in advance, as in printRow stmt = do (id :: Int) <- getFieldValue stmt "ID" (code :: String) <- getFieldValue stmt "Code" (name :: String) <- getFieldValue stmt "Name" putStrLn (unwords [show id, show code, show name]) however, it doesn't work at all if you can't specify the types at compile time: printRow' (names,types,nulls) stmt = do values <- mapM (getFieldValue stmt) names putStrLn $ unwords (map show values) The problem is that getFieldValue returns a value of type (SqlBind a) => a. That is, there's no type information associated with this return value other than it's a valid SQL value. There are no operations in the SqlBind class, it's just a marker as near as I can tell. So when you call getFieldValue, the exact type has to be fixed in some way (by annotations in this example). If the type is not fixed, it can't be used, as shown by the fact that printRow' won't compile. I think this is just the same problem we have with other type classes, e.g., (show (read s)), not anything new. The question is, what can be done about it? Is there anything I, the user can do about it, or can only the library authors solve this problem? Is there something we can change in Haskell to make this sort of thing possible? Thanks, Bryn import Database.HSQL import Database.HSQL.ODBC import System.Environment (getArgs) main = do (connString:sql:_) <- getArgs conn <- connect connString "" "" putStrLn "Connected" stmt <- query conn sql putStrLn $ "Ran query " ++ sql let info = unzip3 $ getFieldsTypes stmt putStrLn (show info) forEachRow' printRow stmt printRow stmt = do (id :: Int) <- getFieldValue stmt "ID" (code :: String) <- getFieldValue stmt "Code" (name :: String) <- getFieldValue stmt "Name" putStrLn (unwords [show id, show code, show name]) printRow' (names,types,nulls) stmt = do values <- mapM (getFieldValue stmt) names putStrLn $ unwords (map show values)