{- | some queries implemented using operations from relational algebra -} module Example.RelationalAlgebra where import Query import Company import qualified Data.Map as Map import Data.Maybe (isNothing, ) import qualified Data.Tree as Tree {- | all employees -} employees :: [Emp] employees = emp {- | all clerks -} clerks :: [Emp] clerks = filter (\e -> job e == Clerk) emp {- | all clerks with salary at least 1000 -} richClerks :: [Emp] richClerks = filter (\e -> job e == Clerk && sal e >= 1000) emp {- | all employees in research department -} researchers :: [Emp] researchers = map fst (filter (\(e,d) -> deptno e == deptno d && dname d == "RESEARCH") (cross emp dept)) researchers0 :: [Emp] researchers0 = map snd (filter (\(d,e) -> deptno e == deptno d) (cross (filter (\d -> dname d == "RESEARCH") dept) emp)) hierarchy :: Tree.Forest Emp hierarchy = let emptrees = map (\e -> Tree.Node e (filter ((Just (empno e) ==) . mgr . Tree.rootLabel) emptrees)) emp in filter (isNothing . mgr . Tree.rootLabel) emptrees {- putStr $ Tree.drawForest $ map (fmap ename) hierarchy -} hierarchyFast :: Tree.Forest Emp hierarchyFast = let emptrees = Map.fromListWith (++) $ map (\e -> (mgr e, [Tree.Node e (Map.findWithDefault [] (Just (empno e)) emptrees)])) emp in Map.findWithDefault [] Nothing emptrees {- | A recursive query: Compute the total salary for each manager and the total set of employees he conducts. -} teamSalaries :: [(String, Int)] teamSalaries = let recurse (Tree.Node e sub0) = let sub1 = map recurse sub0 in Tree.Node (ename e, sal e + sum (map (snd . Tree.rootLabel) sub1)) sub1 in Tree.flatten =<< map recurse hierarchyFast