|
From: Justin B. <jgb...@gm...> - 2009-07-23 15:53:31
|
I don't think the code below can compile. One important aspect of
HaskellDB is that the "shape" of the query is shown in the *type* of
the query.
Looking at your example:
>> q val = 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
The type of q would be based on the columns projected. Assuming
company_name and ticker are both strings, you would get
q :: Query (Rel (RecCons (CompanyName (Expr String)) (RecCons
(Ticker (Expr String)) RecNil)
That is, a type-level tuple which indicates that the query has two
columns, CompanyName and Ticker, both with type String.
Simplying your next example a little bit, I can show that it won't type check:
>> flds cond2 s = let a = (vendor_name << s!vendor_name) # fld
>> b = if cond2
>> then (customer_id << s!customer_id) # a
>> else a
>> in b
>> where
>> fld = company_name << s!company_name # ticker << s!ticker
What is the type of b? We have to look at the query created. When
cond2 is true, then b is:
(customer_id << s!customer_id) # (vendor_name << s!vendor_name) #
company_name << s!company_name # ticker << s!ticker
However, if cond2 is false then b is:
(vendor_name << s!vendor_name) # company_name << s!company_name #
ticker << s!ticker
If cond2 is true, then the type of b can determined by the query shape:
b :: RecCons (CustomerId (Expr Int)) (RecCons (VendorName (Expr
String)) (RecCons (CompanyName (Expr String) (...))
However, if cond2 is false then the type is
b :: RecCons (VendorName (Expr String)) (RecCons (CompanyName (Expr
String) (...))
Since the type of the "then" and "else" arms need to agree, this won't
compile. Its like writing
b = if True then "a" else 1
On Thu, Jul 23, 2009 at 1:37 AM, Artyom
Shalkhakov<art...@gm...> wrote:
> Hi,
>
> 2009/7/22 Keren Lenz <ker...@gm...>:
>> Here is an example (in imperative psudo code of what I mean by dynamic
>> query:
>> Query generate(bool cond1, bool cond2) {
>> Colums c = null;
>> if(cond1)
>> c.add(col1);
>> if(cond3)
>> c.add(col2);
>> Query q = SELECT + c + FROM table_name;
>> return q;
>> }
>
>
>
>> That is, the selected columns are chosen based on runtime conditions.
>> Is that possible with HaskellDB?
>
> I would like to stress how HaskellDB works. You are given atomic building
> blocks (relations, tuples and fields) and some combinators ("glue" that helps
> you combine your building blocks: relational and query operations). What you
> are really doing with HaskellDB is manipulating an abstract syntax tree of a DSL
> embedded in Haskell.
>
> A simple example would be something along these lines [1]:
>
>> q val = 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
>
> It is already somewhat "dynamic". Can we do anything to make it more "dynamic"?
> Yes, we can:
>
>> q flds val = do
>> s <- table stock
>> restrict (fromNull (constant "") (s!company_name)
>> `like` constant ("%"++val++"%"))
>> r <- project (flds s)
>> return r
>
> where flds is simply
>
>> flds s = company_name << s!company_name # ticker << s!ticker)
>
> So now you can do:
>
>> flds cond1 cond2 s = let a = if cond1
>> then (vendor_name << s!vendor_name) # fld
>> else fld
>> b = if cond2
>> then (customer_id << s!customer_id) # a
>> else a
>> in b
>> where
>> fld = company_name << s!company_name # ticker << s!ticker
>
> (don't forget to change the definition of q!)
>
> As the number of conditions grows, this style becomes very inconvenient to
> program in, so you'd need a writer monad over a monoid or something I suppose.
>
> Also, I would like to note that I haven't tested the code given above,
> so I don't
> know if there are any bugs or not. But feel free to ask if there are,
> anyway. :-)
>
> Cheers,
> Artyom Shalkhakov.
>
> [1] http://pseudofish.com/blog/2008/05/11/haskelldb-basics/
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Haskelldb-users mailing list
> Has...@li...
> https://lists.sourceforge.net/lists/listinfo/haskelldb-users
>
|