variables :: Expr a -> [String] variables x = case x of Var y -> [y] _ -> composOpFold [] (++) variables x zeroCount :: Expr a -> Int zeroCount x = case x of Div y (Val 0) -> 1 + zeroCount y _ -> composOpFold 0 (+) zeroCount x simplify :: Expr a -> Expr a simplify x = case x of Sub a b -> simplify $ Add (simplify a) (Neg (simplify b)) Add a b -> case (simplify a, simplify b) of (a',b') | a' == b' -> Mul (Val 2) a' | otherwise -> Add a' b' _ -> composOp simplify x rename :: Tree c -> Tree c rename t = case t of V x -> V ("_" ++ x) _ -> composOp rename t symbols :: Tree c -> [(Tree Var, Tree Typ)] symbols x = case x of SDecl t v -> [(v,t)] _ -> composOpMonoid symbols t constFold :: Tree c -> Tree c constFold e = case e of EAdd x y -> case (f x, f y) of (EInt n, EInt m) -> EInt (n+m) (x',y') -> EAdd x' y' _ -> composOp constFold e increase :: Integer -> Tree c -> Tree c increase k c = case c of S s -> S (s + k) _ -> composOp (increase k) c incrOne :: Name -> Float -> Tree c -> Tree c incrOne d k x = case x of D n _ _ | n == d -> increase k x _ -> composOp (incrOne d k) x salaryBill :: Tree c -> Integer salaryBill x = case x of S s -> s _ -> composOpFold 0 (+) salaryBill x