packages feed

DSH 0.8.0.1 → 0.8.1.0

raw patch · 10 files changed

+158/−99 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Database.DSH: the :: (QA a, Eq a) => Q [a] -> Q a
+ Database.DSH: deriveDSH :: Name -> Q [Dec]
+ Database.DSH: deriveElim :: Name -> Q [Dec]
+ Database.DSH: deriveQA :: Name -> Q [Dec]
+ Database.DSH: deriveTupleRangeQA :: Int -> Int -> Q [Dec]
+ Database.DSH: groupWithKey :: (QA a, QA b, Ord b) => (Q a -> Q b) -> Q [a] -> Q [(b, [a])]
+ Database.DSH: ifThenElse :: QA a => Q Bool -> Q a -> Q a -> Q a
+ Database.DSH: unzip3 :: (QA a, QA b, QA c) => Q [(a, b, c)] -> Q ([a], [b], [c])
+ Database.DSH: zip3 :: (QA a, QA b, QA c) => Q [a] -> Q [b] -> Q [c] -> Q [(a, b, c)]
+ Database.DSH: zipWith3 :: (QA a, QA b, QA c, QA d) => (Q a -> Q b -> Q c -> Q d) -> Q [a] -> Q [b] -> Q [c] -> Q [d]

Files

DSH.cabal view
@@ -1,5 +1,5 @@ Name:                DSH-Version:             0.8.0.1+Version:             0.8.1.0 Synopsis:            Database Supported Haskell Description:   This is a Haskell library for database-supported program execution. Using
examples/Example01.hs view
@@ -30,4 +30,4 @@ runQ q = getConn P.>>= \conn -> (fromQ conn q P.>>= P.print) P.>> disconnect conn  main :: IO ()-main = (runQ ints) P.>> (runQ query1) P.>> (runQ query2)+main = runQ ints P.>> runQ query1 P.>> runQ query2
src/Database/DSH.hs view
@@ -16,6 +16,7 @@ module Database.DSH   ( module Database.DSH.Externals   , Q, QA, Elim, elim, View, view, fromView+  , module Database.DSH.TH   , module Data.String   , module Data.Text   , module Database.HDBC@@ -25,6 +26,7 @@  import Database.DSH.Externals import Database.DSH.Internals (Q,QA,Elim,elim,View,view,fromView)+import Database.DSH.TH  import Data.String (IsString,fromString) import Data.Text (Text)@@ -74,6 +76,9 @@   , zip   , zipWith   , unzip+  , zip3+  , zipWith3+  , unzip3   , fst   , snd   , maybe
src/Database/DSH/Compiler.hs view
@@ -130,27 +130,20 @@ transformE (ListE es) = let ty = reify (undefined :: a)                             qt = ([] :=> transformTy ty)                          in foldr (F.Cons qt) (Nil qt) <$> mapM transformE es-transformE (AppE GroupWith (PairE (gfn :: Exp (ta -> rt)) (e :: Exp el))) = do-  let ty = reify (undefined :: a)+transformE (AppE GroupWithKey (PairE (gfn :: Exp (ta -> rt)) (e :: Exp el))) = do   let tel = reify (undefined :: el)-  let tr = transformTy ty   fn' <- transformLamArg gfn   let (_ :=> tfn@(FFn _ rt)) = typeOf fn'   let gtr = list $ rec [(RLabel "1", rt), (RLabel "2", transformTy $ ListT tel)]   e' <- transformArg e   let (_ :=> te) = typeOf e'   fv <- transformLamArg (LamE id :: Exp (el -> el))-  snd' <- transformLamArg (LamE (\(x :: Exp (rt,[el])) -> AppE Snd x))-  let (_ :=> sndTy) = typeOf snd'   let (_ :=> tfv) = typeOf fv-  return $ App ([] :=> tr)-              (App ([] :=> gtr .-> tr) (Var ([] :=> sndTy .-> gtr .-> tr) "map") snd') -              (ParExpr ([] :=> gtr) $ App ([] :=> gtr)-                  (App ([] :=> te .-> gtr)-                      (App ([] :=> tfn .-> te .-> gtr) (Var ([] :=> tfv .-> tfn .-> te .-> gtr) "groupWith") fv)-                      fn'-                  )-                  e')+  return $ App ([] :=> gtr)+               (App ([] :=> te .-> gtr)+                    (App ([] :=> tfn .-> te .-> gtr) (Var ([] :=> tfv .-> tfn .-> te .-> gtr) "groupWith") fv)+                    fn')+               e' transformE (AppE D.Cons (PairE e1 e2)) = do                                             e1' <- transformE e1                                             e2' <- transformE e2
src/Database/DSH/Externals.hs view
@@ -236,6 +236,12 @@   view (Q e) = (Q (AppE Fst e),Q (AppE Snd e))   fromView (Q a,Q b) = Q (PairE a b) +instance (QA a,QA b,QA c) => View (Q (a,b,c)) (Q a,Q b,Q c) where+  type ToView (Q (a,b,c)) = (Q a,Q b,Q c)+  type FromView (Q a,Q b,Q c) = (Q (a,b,c))+  view (Q e) = (Q (AppE Fst e),Q (AppE Fst (AppE Snd e)),Q (AppE Snd (AppE Snd e)))+  fromView (Q a,Q b,Q c) = Q (PairE a (PairE b c))+ -- IsString instances  instance IsString (Q Text) where@@ -334,6 +340,9 @@ cond :: (QA a) => Q Bool -> Q a -> Q a -> Q a cond (Q c) (Q a) (Q b) = Q (AppE Cond (PairE c (PairE a b))) +ifThenElse :: (QA a) => Q Bool -> Q a -> Q a -> Q a+ifThenElse = cond+ (?) :: (QA a) => Q Bool -> (Q a,Q a) -> Q a (?) c (a,b) = cond c a b @@ -393,7 +402,9 @@ isRight = null . fst . eitherToPair  either :: (QA a,QA b,QA c) => (Q a -> Q c) -> (Q b -> Q c) -> Q (Either a b) -> Q c-either lf rf e = isLeft e ? ((lf . head . fst . eitherToPair) e,(rf . head . snd . eitherToPair) e)+either lf rf e =+  let p = eitherToPair e+  in  head (map lf (fst p) ++ map rf (snd p))  lefts :: (QA a,QA b) => Q [Either a b] -> Q [a] lefts = concatMap (fst . eitherToPair)@@ -453,15 +464,15 @@ filter :: (QA a) => (Q a -> Q Bool) -> Q [a] -> Q [a] filter f (Q as) = Q (AppE Filter (PairE (LamE (toLam f)) as)) +groupWithKey :: (QA a,QA b,Ord b) => (Q a -> Q b) -> Q [a] -> Q [(b,[a])]+groupWithKey f (Q as) = Q (AppE GroupWithKey (PairE (LamE (toLam f)) as))+ groupWith :: (QA a,QA b,Ord b) => (Q a -> Q b) -> Q [a] -> Q [[a]]-groupWith f (Q as) = Q (AppE GroupWith (PairE (LamE (toLam f)) as))+groupWith f as = map snd (groupWithKey f as)  sortWith :: (QA a,QA b,Ord b) => (Q a -> Q b) -> Q [a] -> Q [a] sortWith f (Q as) = Q (AppE SortWith (PairE (LamE (toLam f)) as)) -the :: (QA a,Eq a) => Q [a] -> Q a-the (Q as) = Q (AppE The as)- last :: (QA a) => Q [a] -> Q a last (Q as) = Q (AppE Last as) @@ -549,8 +560,20 @@ zipWith f as bs = map (\e -> f (fst e) (snd e)) (zip as bs)  unzip :: (QA a,QA b) => Q [(a,b)] -> Q ([a],[b])-unzip (Q as) = Q (AppE Unzip as)+unzip as = pair (map fst as) (map snd as) +zip3 :: (QA a,QA b,QA c) => Q [a] -> Q [b] -> Q [c] -> Q [(a,b,c)]+zip3 as bs cs = map (\abc -> fromView (fst abc,fst (snd abc),snd (snd abc))) (zip as (zip bs cs))++zipWith3 :: (QA a,QA b,QA c,QA d) => (Q a -> Q b -> Q c -> Q d) -> Q [a] -> Q [b] -> Q [c] -> Q [d]+zipWith3 f as bs cs = map (\e -> (case view e of (a,b,c) -> f a b c))+                          (zip3 as bs cs)++unzip3 :: (QA a,QA b,QA c) => Q [(a,b,c)] -> Q ([a],[b],[c])+unzip3 abcs = fromView ( map (\e -> (case view e of (a,_,_) -> a)) abcs+                       , map (\e -> (case view e of (_,b,_) -> b)) abcs+                       , map (\e -> (case view e of (_,_,c) -> c)) abcs)+ -- * Set-oriented operations  nub :: (QA a,Eq a) => Q [a] -> Q [a]@@ -637,11 +660,5 @@ > words > unlines > unwords--Zipping and unzipping lists:--> zip3-> zipWith3-> unzip3  -}
src/Database/DSH/Internals.hs view
@@ -37,7 +37,6 @@     Concat          :: (Reify a) => Fun [[a]] [a]     Head            :: Fun [a] a     Tail            :: Fun [a] [a]-    The             :: Fun [a] a     Init            :: Fun [a] [a]     Last            :: Fun [a] a     Null            :: Fun [a] Bool@@ -48,7 +47,6 @@     Sum             :: Fun [a] a     Maximum         :: Fun [a] a     Minimum         :: Fun [a] a-    Unzip           :: (Reify a,Reify b) => Fun [(a,b)] ([a],[b])     Nub             :: Fun [a] [a]     Add             :: Fun (a,a) a     Mul             :: Fun (a,a) a@@ -71,7 +69,7 @@     Zip             :: Fun ([a],[b]) [(a,b)]     Map             :: Fun (a -> b,[a]) [b]     Filter          :: Fun (a -> Bool,[a]) [a]-    GroupWith       :: (Reify b) => Fun (a -> b,[a]) [[a]]+    GroupWithKey    :: Fun (a -> b,[a]) [(b,[a])]     SortWith        :: Fun (a -> b,[a]) [a]     TakeWhile       :: Fun (a -> Bool,[a]) [a]     DropWhile       :: Fun (a -> Bool,[a]) [a]@@ -124,7 +122,6 @@     show Concat = "concat"     show Head = "head"     show Tail = "tail"-    show The = "the"     show Init = "init"     show Last = "last"     show Null = "null"@@ -135,7 +132,6 @@     show Sum = "sum"     show Maximum = "maximum"     show Minimum = "minimum"-    show Unzip = "unzip"     show Nub = "nub"     show IntegerToDouble = "integerToDouble"     show Add = "+"@@ -159,7 +155,7 @@     show Zip = "zip"     show Map = "map"     show Filter = "filter"-    show GroupWith = "groupWith"+    show GroupWithKey = "groupWithKey"     show SortWith = "sortWith"     show TakeWhile = "takeWhile"     show DropWhile = "dropWhile"@@ -193,7 +189,6 @@  instance (Reify a, Reify b) => Reify (a -> b) where   reify _ = ArrowT (reify (undefined :: a)) (reify (undefined :: b))-  -- Utility functions 
src/Database/DSH/Interpreter.hs view
@@ -60,14 +60,14 @@       (ListE as1) <- evaluate c as       (ListE as2) <- evaluate c (ListE (map f as1))       return $ ListE (map fst (filter (\(_,BoolE b) -> b) (zip as1 as2))) -    AppE GroupWith (PairE (LamE f) as) -> do+    AppE GroupWithKey (PairE (LamE f) as) -> do       (ListE as1) <- evaluate c as-      (ListE as2) <- evaluate c (ListE (map f as1))+      (ListE ks1) <- evaluate c (ListE (map f as1))       return $ ListE-             $ map (ListE . map fst)-             $ groupBy (\(_,a1) (_,a2) -> equExp a1 a2)-             $ sortBy (\(_,a1) (_,a2) -> compareExp a1 a2)-             $ zip as1 as2+             $ map (\kas1 -> PairE (fst (head kas1)) (ListE (map snd kas1)))+             $ groupBy (\(k1,_) (k2,_) -> equExp k1 k2)+             $ sortBy (\(k1,_) (k2,_) -> compareExp k1 k2)+             $ zip ks1 as1     AppE SortWith (PairE (LamE f) as) -> do       (ListE as1) <- evaluate c as       (ListE as2) <- evaluate c $ ListE (map f as1) @@ -77,33 +77,22 @@              $ zip as1 as2     (AppE Max (PairE e1 e2)) ->       case reify (undefined :: a) of-          IntegerT -> do-                        (IntegerE v1) <- evaluate c e1-                        (IntegerE v2) <- evaluate c e2-                        return $ IntegerE (max v1 v2)-          DoubleT -> do -                        (DoubleE v1) <- evaluate c e1-                        (DoubleE v2) <- evaluate c e2-                        return $ DoubleE (max v1 v2)+          IntegerT -> do (IntegerE v1) <- evaluate c e1+                         (IntegerE v2) <- evaluate c e2+                         return $ IntegerE (max v1 v2)+          DoubleT  -> do (DoubleE v1) <- evaluate c e1+                         (DoubleE v2) <- evaluate c e2+                         return $ DoubleE (max v1 v2)           _ -> $impossible     (AppE Min (PairE e1 e2)) ->       case reify (undefined :: a) of-          IntegerT -> do-                        (IntegerE v1) <- evaluate c e1-                        (IntegerE v2) <- evaluate c e2-                        return $ IntegerE (min v1 v2)-          DoubleT -> do-                        (DoubleE v1) <- evaluate c e1-                        (DoubleE v2) <- evaluate c e2-                        return $ DoubleE (min v1 v2)+          IntegerT -> do (IntegerE v1) <- evaluate c e1+                         (IntegerE v2) <- evaluate c e2+                         return $ IntegerE (min v1 v2)+          DoubleT  -> do (DoubleE v1) <- evaluate c e1+                         (DoubleE v2) <- evaluate c e2+                         return $ DoubleE (min v1 v2)           _ -> $impossible-    AppE The as -> do-      (ListE as1) <- evaluate c as-      case as1 of-        [] -> error "Database.DSH.Interpreter.the: empty list"-        (x : xs) -> return $ if all (equExp x) xs-                                then x-                                else error "Database.DSH.Interpreter.the: non-identical elements"     AppE Last as -> do       (ListE as1) <- evaluate c as       return $ last as1@@ -162,9 +151,6 @@       (ListE as1) <- evaluate c as       (ListE bs1) <- evaluate c bs       return $ ListE (zipWith PairE as1 bs1)-    AppE Unzip as -> do-      (ListE as1) <- evaluate c as-      return $ PairE (ListE (map (\(PairE a _) -> a) as1)) (ListE (map (\(PairE _ b) -> b) as1))     AppE Nub as -> do       (ListE as1) <- evaluate c as       return $ ListE (nubBy equExp as1)
src/Database/DSH/TH.hs view
@@ -1,10 +1,21 @@-module Database.DSH.TH (deriveQA, deriveTupleRangeQA, deriveElim) where+module Database.DSH.TH (deriveDSH, deriveQA, deriveTupleRangeQA, deriveElim) where  import qualified Database.DSH.Internals  as DSH import qualified Database.DSH.Impossible as DSH  import Language.Haskell.TH+import Control.Monad +-----------------------------------------+-- Deriving all DSH-relevant instances --+-----------------------------------------++deriveDSH :: Name -> Q [Dec]+deriveDSH n = do+  qa <- deriveQA n+  el <- deriveElim n+  return (qa ++ el)+ ----------------- -- Deriving QA -- -----------------@@ -30,7 +41,7 @@ deriveTupleRangeQA :: Int -> Int -> Q [Dec] deriveTupleRangeQA x y = fmap concat (mapM (deriveQA . tupleTypeName) [x .. y]) --- Derive the Rep type function+-- Deriving the Rep type function  deriveRep :: Type -> [Con] -> Dec deriveRep typ cons = TySynInstD ''DSH.Rep [typ] (deriveRepCons cons)@@ -47,7 +58,7 @@   ts -> foldr1 (AppT . AppT (ConT ''(,)))                (map (AppT (ConT ''DSH.Rep)) ts) --- Derive the toExp function of the QA class+-- Deriving the toExp function of the QA class  deriveToExp :: [Con] -> Q Dec deriveToExp [] = fail errMsgExoticType@@ -80,7 +91,7 @@ deriveToExpMainExp [name] = AppE (VarE 'DSH.toExp) (VarE name) deriveToExpMainExp names  = foldr1 (AppE . AppE (ConE 'DSH.PairE))                                    (map (AppE (VarE 'DSH.toExp) . VarE) names)--- Derive to frExp function of the QA class+-- Deriving to frExp function of the QA class  deriveFrExp :: [Con] -> Q Dec deriveFrExp cons = do@@ -131,15 +142,14 @@   resultTyName <- newName "r"   let resTy = VarT resultTyName   let ty = foldl AppT (ConT name) (map (VarT . tyVarBndrToName) tyVarBndrs)-  let context = (ClassP ''DSH.QA [ty])    :-                (ClassP ''DSH.QA [resTy]) :+  let context = ClassP ''DSH.QA [resTy] :                 map (\tv -> ClassP ''DSH.QA [VarT (tyVarBndrToName tv)]) tyVarBndrs   let instanceHead = AppT (AppT (ConT ''DSH.Elim) ty) resTy   let eliminatorDec = deriveEliminator ty resTy cons   elimDec <- deriveElimFun cons   return [InstanceD context instanceHead [eliminatorDec,elimDec]] --- Derive the Eliminator type function+-- Deriving the Eliminator type function  deriveEliminator :: Type -> Type -> [Con] -> Dec deriveEliminator typ resTy cons = TySynInstD ''DSH.Eliminator [typ,resTy] (deriveEliminatorCons resTy cons)@@ -147,17 +157,17 @@ deriveEliminatorCons :: Type -> [Con] -> Type deriveEliminatorCons _ []  = error errMsgExoticType deriveEliminatorCons resTy cs  =-  foldr (AppT . AppT ArrowT)+  foldr (AppT . AppT ArrowT . deriveEliminatorCon resTy)         (AppT (ConT ''DSH.Q) resTy)-        (map (deriveEliminatorCon resTy) cs)+        cs  deriveEliminatorCon :: Type -> Con -> Type deriveEliminatorCon resTy con =-  foldr (AppT . AppT ArrowT)+  foldr (AppT . AppT ArrowT . AppT (ConT ''DSH.Q))         (AppT (ConT ''DSH.Q) resTy)-        (map (AppT (ConT ''DSH.Q)) (conToTypes con))+        (conToTypes con) --- Derive the elim function of the Elim type class+-- Deriving the elim function of the Elim type class  deriveElimFun :: [Con] -> Q Dec deriveElimFun cons = do@@ -169,9 +179,9 @@   en  <- newName "e"   fns <- mapM (\ _ -> newName "f") cons   let fes = map VarE fns-  let pats1 = (ConP 'DSH.Q [VarP en]) : map VarP fns+  let pats1 = ConP 'DSH.Q [VarP en] : map VarP fns -  fes2 <- sequence (zipWith deriveElimToLamExp fes (map (length . conToTypes) cons))+  fes2 <- zipWithM deriveElimToLamExp fes (map (length . conToTypes) cons)    let e       = VarE en   let liste   = AppE (ConE 'DSH.ListE) (ListE (deriveElimFunClauseExp e fes2))
tests/Main.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE TemplateHaskell, GADTs, TypeFamilies, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall -O3 -fno-warn-orphans #-}+ module Main where  import qualified Database.DSH as Q@@ -12,6 +15,8 @@ import Test.QuickCheck import Test.QuickCheck.Monadic +import Data.DeriveTH+ import Data.List import Data.Maybe import Data.Either@@ -25,6 +30,26 @@ instance Arbitrary Text where   arbitrary = fmap Text.pack arbitrary +data D1 = C11 deriving (Eq,Ord,Show)+derive makeArbitrary ''D1+Q.deriveDSH ''D1++data D2 = C21 | C22 deriving (Eq,Ord,Show)+derive makeArbitrary ''D2+Q.deriveDSH ''D2++data D3 a = C31 a | C32 deriving (Eq,Ord,Show)+derive makeArbitrary ''D3+Q.deriveDSH ''D3++data D4 a = C41 a | C42 | C43 a a | C44 a a a deriving (Eq,Ord,Show)+derive makeArbitrary ''D4+Q.deriveDSH ''D4++data D5 a b c d e = C51 { c511 :: a, c512 :: (a,b,c,d) } | C52 | C53 a b | C54 (a,b,c) | C55 a b c d e deriving (Eq,Ord,Show)+derive makeArbitrary ''D5+Q.deriveDSH ''D5+ getConn :: IO Connection getConn = connectPostgreSQL "user = 'giorgidz' password = '' host = 'localhost' dbname = 'giorgidz'" @@ -60,6 +85,16 @@     qc prop_maybe_integer     putStrPad "Either Integer Integer: "     qc prop_either_integer+    putStrPad "D1: "+    qc prop_d1+    putStrPad "D2: "+    qc prop_d2+    putStrPad "D3: "+    qc prop_d3+    putStrPad "D4: "+    qc prop_d4+    putStrPad "D5: "+    qc prop_d5      putStrLn ""     putStrLn "Equality, Boolean Logic and Ordering"@@ -192,8 +227,6 @@     qc prop_map     putStrPad "filter"     qc prop_filter-    putStrPad "the"-    qc prop_the     putStrPad "last"     qc prop_last     putStrPad "init"@@ -250,10 +283,16 @@     qc prop_lookup     putStrPad "zip"     qc prop_zip+    putStrPad "zip3"+    qc prop_zip3     putStrPad "zipWith"     qc prop_zipWith+    putStrPad "zipWith3"+    qc prop_zipWith3     putStrPad "unzip"     qc prop_unzip+    putStrPad "unzip3"+    qc prop_unzip3     putStrPad "nub"     qc prop_nub @@ -327,6 +366,21 @@ prop_either_integer :: Either Integer Integer -> Property prop_either_integer = makeProp id id +prop_d1 :: D1 -> Property+prop_d1 = makeProp id id++prop_d2 :: D2 -> Property+prop_d2 = makeProp id id++prop_d3 :: D3 Integer -> Property+prop_d3 = makeProp id id++prop_d4 :: D4 Integer -> Property+prop_d4 = makeProp id id++prop_d5 :: D5 Integer Integer Integer Integer Integer -> Property+prop_d5 = makeProp id id+ -- * Equality, Boolean Logic and Ordering  prop_infix_and :: (Bool,Bool) -> Property@@ -452,14 +506,6 @@ prop_init  :: [Integer] -> Property prop_init  = makePropNotNull Q.init init -prop_the   :: [Integer] -> Property-prop_the l =-        allEqual l-    ==> makeProp Q.the the l-  where-    allEqual []     = False-    allEqual (x:xs) = all (x ==) xs- prop_index :: ([Integer], Integer)  -> Property prop_index (l, i) =         i > 0 && i < fromIntegral (length l)@@ -544,7 +590,7 @@  prop_break :: (Integer, [Integer]) -> Property prop_break = makeProp (uncurryQ $ Q.break . (Q.==))-                     (uncurry   $   break . (==) . fromIntegral)+                      (uncurry   $   break . (==) . fromIntegral)  prop_elem :: (Integer, [Integer]) -> Property prop_elem = makeProp (uncurryQ Q.elem)@@ -566,6 +612,17 @@  prop_unzip :: [(Integer, Integer)] -> Property prop_unzip = makeProp Q.unzip unzip++prop_zip3 :: ([Integer], [Integer],[Integer]) -> Property+prop_zip3 = makeProp (\q -> (case Q.view q of (as,bs,cs) -> Q.zip3 as bs cs))+                     (\(as,bs,cs) -> zip3 as bs cs)++prop_zipWith3 :: ([Integer], [Integer],[Integer]) -> Property+prop_zipWith3 = makeProp (\q -> (case Q.view q of (as,bs,cs) -> Q.zipWith3 (\a b c -> a + b + c) as bs cs))+                         (\(as,bs,cs) -> zipWith3 (\a b c -> a + b + c) as bs cs)++prop_unzip3 :: [(Integer, Integer, Integer)] -> Property+prop_unzip3 = makeProp Q.unzip3 unzip3  prop_nub :: [Integer] -> Property prop_nub = makeProp Q.nub nub
tests/Makefile view
@@ -1,15 +1,11 @@ all: cabal-		ghc -Wall -O3 -fno-warn-orphans --make Main.hs -o Main+		ghc --make Main.hs -o Main 		./Main -hpc: cabal-		mkdir tmp-		ghc -Wall -i../src -i../dist/build/autogen -outputdir tmp -fforce-recomp -O3 -fhpc --make Main.hs -o Main-		./Main-		hpc report Main-		hpc markup Main- cabal: clean+		cabal install quickcheck+		cabal install hdbc-postgresql+		cabal install derive 		cd ..; cabal install; cd tests;  clean: