This page describes the original version of HaskellDb, available from http://www.haskell.org/haskellDB/index.html There is a newer version at http://haskelldb.sourceforge.net/ which works with GHC and supports more backends. ---- Examples are available at http://www.haskell.org/haskellDB/example.html. Here are some snippets: StructuredQueryLanguage SELECT X.first_name, X.last_name FROM Authors AS X HaskellLanguage (using HaskellDb): names = do x <- table authors project (first_name = x!first_name, last_name = x!last_name ) The "!" operator selects an attribute from a relation (like "." in StructuredQueryLanguage). The result is bound to ''names''. Since it's plain HaskellLanguage code one can use any sort of combinators he want to use (e.g. ExtensibleMarkupLanguage combinators to create reports). ---- ''What command(s) actually go to the database engine? Or, is the implementation done in Haskell? If so, what would it look like if other languages wanted to access the same data?'' HaskellDb defines some relational algebra combinators (e.g. project, restrict, order) and you use them to declare your query. The constructed query object is eventually given to a particular database driver and it'll then be automatically transformed in a statement string. So you write code like: samecity = do x <- table authors y <- table authors restrict (x!au_id .<>. y!au_id) restrict (x!city .==. y!city) project (au_fname = x!au_fname, au_lname = x!au_lname, city = x!city) And it becomes: SELECT DISTINCT au_fname1 as au_fname, au_lname1 as au_lname, city1 as city FROM (SELECT DISTINCT au_id as au_id2 ,city as city2 FROM authors as T1) as T1, (SELECT DISTINCT au_fname as au_fname1, au_id as au_id1, au_lname as au_lname1, city as city1 FROM authors as T1) as T2 WHERE (au_id1 <> au_id2) AND (city1 = city2) ''Which is stupid-translator-ese for:'' SELECT DISTINCT t1.au_fname as au_fname, t1.au_lname as au_lname, t1.city as city FROM authors as t1, authors as t2 WHERE (t1.au_id <> t2.au_id) AND (t1.city = t2.city) ''Right?'' ---- The truly great thing about HaskellDB is that it's strongly typed, which means you can't express a query that's illogical, e.g. joining a string column to a date column. This means databases (and DB programmers) that play fast and loose with type conversions will have to explicitly cast at the DB side if they want to match incompatible types. Of course, strong typing is probably why you're using Haskell in the first place... ---- ErlangLanguage has a similar sort of thing called Mnesia where they use list comprehension syntax to query databases. ---- CategoryHaskell