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 >> > |