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
newtype Fix f = Fix { unFix :: f (Fix f) } | |
-- Analog to Expr = ExprR Expr | |
type Expr = Fix ExprR |
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
cst = Fix . Cst | |
var = Fix . Var | |
add = Fix . Op Add | |
mul = Fix . Op Mul |
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") ]] |
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
instance Functor ExprR where | |
fmap _ (Cst c) = Cst c | |
fmap _ (Var v) = Var v | |
fmap f (Op opType xs) = Op opType (map f 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
cataExpr :: (ExprR a -> a) -> Expr -> a | |
cataExpr algebra = | |
algebra | |
. fmap (cataExpr algebra) | |
. unFix |
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
cata :: Functor f => (f a -> a) -> Fix f -> a | |
cata algebra = | |
algebra | |
. fmap (cata algebra) | |
. unFix |
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 :: Expr -> String | |
prn = cata algebra where | |
algebra (Cst n) = show n | |
algebra (Var x) = x | |
algebra (Op Add xs) = "(+ " ++ unwords xs ++ ")" | |
algebra (Op Mul xs) = "(* " ++ unwords 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
eval :: Env -> Expr -> Int | |
eval env = cata algebra where | |
algebra (Cst n) = n | |
algebra (Var x) = env Map.! x | |
algebra (Op Add xs) = sum xs | |
algebra (Op Mul xs) = product 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
dependencies :: Expr -> Set.Set Id | |
dependencies = cata algebra where | |
algebra (Cst _) = Set.empty | |
algebra (Var x) = Set.singleton x | |
algebra (Op _ xs) = Set.unions 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
optimizeAdd :: ExprR Expr -> Expr | |
optimizeAdd op@(Op Add _) = optimizeOp op 0 (+) | |
optimizeAdd e = Fix e | |
optimizeMul :: ExprR Expr -> Expr | |
optimizeMul op@(Op Mul xs) | |
| not (null (dropWhile (/= cst 0) xs)) = cst 0 | |
| otherwise = optimizeOp op 1 (*) | |
optimizeMul e = Fix e |