[Update to doc HTML files. alistair@abayley.org**20070106230225] { hunk ./doc/html/Database-Enumerator.html 104 ->Bind Parameters +>Rank-2 types and ($) hunk ./doc/html/Database-Enumerator.html 109 +>Bind Parameters +
Rank-2 types and ($) +

In some examples we use the application operator ($) instead of parentheses + (some might argue that his is a sign of developer laziness). + At first glance, ($) and normal function application seem to be interchangeable + e.g. +

 liftIO (putStrLn (show x))
+

is equivalent to +

 liftIO $ putStrLn $ show x
+

But they're not, and the places where they differ usually involve + higher-rank types, like our DBM monad. + That's because ($) has type (a -> b) -> a -> b, which limits it + to rank-1 typed functions, a restriction which does not affect normal + function application. +

Here's an example where ($) fails: + we supply a simple test program in the README file. + If you change the withSession line to use ($), like so + (and remove the matching end-parenthese): +

   withSession (connect "sqlite_db") $ do
+

then you get the error: +

 Main.hs:7:38:
+     Couldn't match expected type `forall mark. DBM mark Session a'
+            against inferred type `a1 b'
+     In the second argument of `($)', namely
+       ...
+

Another way of rewriting it is like this, where we separate the + DBM action into another function: +

 {-# OPTIONS -fglasgow-exts #-}
+ module Main where
+ import Database.Sqlite.Enumerator
+ import Database.Enumerator
+ import Control.Monad.Trans (liftIO)
+ main = flip catchDB reportRethrow $
+   withSession (connect "sqlite_db") hello
+
+ hello = withTransaction RepeatableRead $ do
+     let iter (s::String) (_::String) = result s
+     result <- doQuery (sql "select 'Hello world.'") iter ""
+     liftIO (putStrLn result)
+

which gives this error: +

 Main.hs:9:2:
+     Inferred type is less polymorphic than expected
+       Quantified type variable `mark' is mentioned in the environment:
+         hello :: DBM mark Session () (bound at Main.hs:15:0)
+         ...
+

However, if you add this type declaration: +

 hello :: DBM mark Session ()
+

then the compiler is happy, which shows that our rank-2 typed + DBM monad isn't entirely incompatible with ($). +

For You may have noticed that For bind values, - we have to tell the compiler about the types. +> literal + bind values, we have to tell the compiler the type of the literal. hunk ./doc/html/Database-Enumerator.html 1723 ->.): +>): hunk ./doc/html/Database-Enumerator.html 1816 -> the results of the first iteratee are discarded. This is not required, - but in this case the only column is a in this example we choose to discard the results of the first iteratee. + This is not necessary, but in this case the only column is a + , - and the values are already saved elsewhere. +>, and the values are already saved + in the prepared statement object. hunk ./doc/html/Database-Enumerator.html 1859 - For PostgreSQL, this will be until either the transaction or session ends. + For PostgreSQL, this will be until the transaction (or session) ends. hunk ./doc/html/Database-Enumerator.html 1935 - The reason it's different is that Oracle requires two things: + The reason it's different is that: hunk ./doc/html/Database-Enumerator.html 1939 -> the parent cursor must remain open while processing the children +> Oracle requires that the parent cursor must remain open + while processing the children hunk ./doc/html/Database-Enumerator.html 1952 -> our current design prevents marshalling of the value in the result-set +> our current Oracle implementation prevents marshalling + of the value in the result-set hunk ./doc/html/Database-Enumerator.html 1961 ->Contrast this with the PostgreSQL - example, where the entire result-set is processed to give a +>Contrast this with the PostgreSQL example above, + where the entire result-set is processed to give a hunk ./doc/html/Database-Enumerator.html 1996 - from the PostgreSQL exanple). + from the PostgreSQL example). hunk ./doc/html/Database-Enumerator.html 2006 ->Maybe CalendarTime) Query ColumnBufferDBType (fPQsetClientEncoding :: DBHandle -> CString -> IO CStringcolValCalTime :: ResultSetHandle -> Int -> Int -> IO CalendarTimefPQsetClientEncoding :: DBHandle -> CString -> IO CString CalendarTimePGType IntegerPGTypecolValCalTime :: ResultSetHandle -> Int -> Int -> IO CalendarTimepgDatetimetoCalTime :: String -> CalendarTimepgDatetimetoParts :: String -> (Int, Int, Int, Int, Int, Double, Int)calTimeToPGDatetime :: CalendarTime -> StringpgDatetimetoCalTime :: String -> CalendarTimepgDatetimetoParts :: String -> (Int, Int, Int, Int, Int, Double, Int)calTimeToPGDatetime :: CalendarTime -> StringAssumes CalendarTime is also UTC i.e. ignores ctTZ component. +calTimeToPGDatetimeDatabase.UtilcolValCalTimeDatabase.PostgreSQL.PGFunctionsfPQsetClientEncodingDatabase.PostgreSQL.PGFunctionsForeign.C.UnicodefromUTF8EForeign.C.UnicodefromUTF8WEForeign.C.UnicodeForeign.C.UTF8Foreign.C.UnicodeForeign.C.UTF8Foreign.C.UnicodeForeign.C.UTF8pgDatetimetoCalTimeDatabase.UtilpgDatetimetoPartsDatabase.UtilForeign.C.UnicodeForeign.C.UTF8Foreign.C.UnicodeForeign.C.UTF8Foreign.C.UnicodeForeign.C.UTF8Foreign.C.UnicodeForeign.C.UTF8