This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Env = Map.Map String Int | |
eval :: Env -> Expr -> Int | |
eval env (Cst n) = n | |
eval env (Var v) = env Map.! v | |
eval env (Op Add xs) = sum $ map (eval env) xs | |
eval env (Op Mul xs) = product $ map (eval env) xs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
partial :: Env -> Expr -> Expr | |
partial env e@(Var v) = | |
case Map.lookup v env of | |
Nothing -> e | |
Just n -> cst n | |
partial env (Op opType xs) = Op opType (map (partial env) xs) | |
partial env e = e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies :: Expr -> Set.Set Id | |
dependencies (Var v) = Set.singleton v | |
dependencies (Op _ xs) = foldl1' Set.union (map dependencies xs) | |
dependencies e = Set.empty | |
eval' :: Env -> Expr -> Int | |
eval' env e = | |
case optimize (partial env e) of | |
Cst n -> n | |
e -> error $ "Missing vars: " ++ show (dependencies e) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> let e = add [ cst(1) | |
, cst(2) | |
, mul [cst(0), var("x"), var("y")] | |
, mul [cst(1), var("y"), cst(2)] | |
, add [cst(0), var("x") ]] | |
> prn e | |
"(+ 1 2 (* 0 x y) (* 1 y 2) (+ 0 x))" | |
> prn (optimize e) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> let e = add [ cst(1) | |
, cst(2) | |
, mul [cst(0), var("x"), var("y")] | |
, mul [cst(1), var("y"), cst(2)] | |
, add [cst(0), var("x") ]] | |
> let env = Map.fromList [("y", 0)] | |
> prn (partial env e) | |
"(+ 1 2 (* 0 x 0) (* 1 0 2) (+ 0 x))" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> prn (partial env e) | |
"(+ 1 2 (* 0 x 0) (* 1 0 2) (+ 0 x))" | |
> prn (optimize (partial env e)) | |
"(+ 3 x)" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> let e = add [ cst(1) | |
, cst(2) | |
, mul [cst(0), var("x"), var("y")] | |
, mul [cst(1), var("y"), cst(2)] | |
, add [cst(0), var("x") ]] | |
> let env = Map.fromList [("x", 1), ("y", 2)] | |
> prn e | |
"(+ 1 2 (* 0 x y) (* 1 y 2) (+ 0 x))" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> let e = add [ cst(1) | |
, cst(2) | |
, mul [cst(0), var("x"), var("y")] | |
, mul [cst(1), var("y"), cst(2)] | |
, add [cst(0), var("x") ]] | |
> let env = Map.fromList [("x", 1)] | |
> eval' env e | |
*** Exception: Missing vars: fromList ["y"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Id = String | |
data OpType = Add | Mul deriving (Show, Eq, Ord) | |
data ExprR r | |
= Cst Int | |
| Var Id | |
| Op OpType [r] | |
deriving (Show, Eq, Ord) |