From: Bjorn B. <bj...@br...> - 2009-07-24 06:32:41
|
Yes, don't declare a type for the query, let the type checker infer it. /Bjorn 2009/7/24 Artyom Shalkhakov <art...@gm...>: > 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 >>> >> > > ------------------------------------------------------------------------------ > _______________________________________________ > Haskelldb-users mailing list > Has...@li... > https://lists.sourceforge.net/lists/listinfo/haskelldb-users > |