|
From: Artyom S. <art...@gm...> - 2009-07-24 04:52:32
|
Hi Justin,
It's a pity I can't test the code ATM, but isn't there a way
to find "the most general type" of the query?
Anyway, thanks for clarifying that. Next time, I will have to check
the code I post.
2009/7/23 Justin Bailey <jgb...@gm...>:
> 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
>>
>
|