Skip to content

Instantly share code, notes, and snippets.

@deque-blog
Last active January 21, 2017 21:09
Show Gist options
  • Save deque-blog/757fe47a3474915efaf6c8b7cc2c7562 to your computer and use it in GitHub Desktop.
Save deque-blog/757fe47a3474915efaf6c8b7cc2c7562 to your computer and use it in GitHub Desktop.
optimize :: Expr -> Expr
optimize op@(Op Add ys) = optimizeOp Add (map optimize ys) 0 (+)
optimize op@(Op Mul ys)
| not (null (dropWhile (/= cst 0) xs)) = cst 0
| otherwise = optimizeOp Mul xs 1 (*)
where xs = map optimize ys
optimize e = e
optimizeOp :: OpType -> [Expr] -> Int -> (Int -> Int -> Int) -> Expr
optimizeOp opType xs neutral combine =
let (constants, vars) = partition isCst xs
constantsVal = map (\(Cst x) -> x) constants
sumCst = foldl' combine neutral constantsVal
in case vars of
[] -> cst sumCst
[y] | sumCst == neutral -> y
ys | sumCst == neutral -> Op opType ys
ys -> Op opType (cst sumCst : ys)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment