HaskellDB Basics
HaskellDB is a domain specific embedded language for specifying database queries and operations.
The upside of this is the full Haskell language for writing queries and the Haskell compiler and type checker for validating database code. The (big) downside is the error messages are horribly cryptic; although once is compiles it is likely to be correct.
The original version of HaskellDB was re-written to be more portable and usable in more situations. Unfortunately, the documentation is out of step with the current code.
Installation is particularly tricky.
The following is an example query:
stockInfo :: Database -> String
-> IO [(CompanyName, TickerSymbol)]
stockInfo db val = do
let q = do
s < - table stock
restrict (fromNull (constant "") (s!company_name)
`like` constant ("%"++val++"%"))
r <- project (company_name << s!company_name #
ticker << s!ticker)
return r
rs <- query db q
return $ map (\r ->
(maybe "" id (r!company_name), r!ticker)) rs
To run the query, a database connection detail is passed, along with the search string. In this case, find all company names and stock tickers where the company name contains ‘news’.
vals :: IO [(CompanyName, TickerSymbol)]
vals = withDB $ \db -> stockInfo db "news"
The result is:
[("APN NEWS & MEDIA LIMITED","APN"),
("WEST AUSTRALIAN NEWSPAPERS HOLDINGS LIMITED","WAN"),
("NEWS CORPORATION","NWS"),
("NEWSAT LIMITED","NWT")]
The database connection can be abstracted into a separate module:
module StockConnection where
import Database.HaskellDB
import Database.HaskellDB.HSQL.MySQL
opts = MySQLOptions {
server="localhost",
db="stocks",
uid="stock_user",
pwd="stock_pass"}
withDB :: (Database -> IO a) -> IO a
withDB = mysqlConnect opts
If you want more information, try:
- Introductory Slides (pdf) – a gentle introduction.
- Student Paper: HaskellDB Improved (pdf) – the report of the re-write.
- Database.HaskellDB.Query – list of the query combinators.
This approach to database programming is included in Microsoft’s .NET platform, called LINQ. Eric Meijer is the link between the two.

May 12th, 2008 at 9:06 am
Shouldn’t vals have a \?
i.e.
vals = withDB $ \db -> …
May 12th, 2008 at 9:12 am
Yes. And the backslash was also missing for ‘r’ on the lamba expression supplied to map. Wordpress ate the backslashes. Thanks for noticing! Now fixed.
May 13th, 2008 at 8:06 am
Glad you posted this. HaskellDB is an under-appreciated library that suffers from some severely bit-rotted documentation. The code itself is pretty solid.
IMHO the real power of this library comes from the ability to compose queries. I’ve been using it to generate a PHP/SQL data-access layer from queries defined in Haskell using HaskellDB. I can, for example, define a common condition on a field and add it to any query I wish:
restrictAge age field = do
restrict (field .>. age)
Which can then be used as (assuming user is a table with age-related data in it):
selectGame user game includeMature = do
t