data Expr = Num Integer | Add Expr Expr | Mul Expr Expr
eval :: Expr -> Integer eval (Num n) = n eval (Add a b) = eval a + eval b eval (Mul a b) = eval a * eval b
data Expr = Num Integer
| Var Name -- new
| Add Expr Expr
| Mul Expr Expr
type Name = String
vars :: Expr -> [Name] vars (Num n) = [] vars (Var x) = [x] vars (Add a b) = vars a `union` vars b vars (Mul a b) = vars a `union` vars b
union
Data.List
) instead of
++
eval :: [(Name,Integer)] -> Expr -> Integer
eval env (Num n) = n
eval env (Var x) = case lookup x env of
Just n -> n
Nothing -> error ("undefined variable: "++x)
eval env (Add a b) = eval env a + eval env b
eval env (Mul a b) = eval env a * eval env b
lookup :: Eq key => [(key,value)] -> key -> Maybe value
error
0
eval
Maybe Integer
data Maybe a = Nothing | Just a
lookup
lookup :: Eq key => [(key,value)] -> key -> Maybe value lookup k [] = Nothing lookup k ((k',v):kvs) | k' == k = Just v | otherwise = lookup k kvs
diff :: Expr -> Name -> Expr
diff :: Expr -> Name -> Expr diff (Num n) x = Num 0 diff (Var y) x = if y==x then Num 1 else Num 0 diff (Add a b) x = Add (diff a x) (diff b x) diff (Mul a b) x = Add (Mul a (diff b x)) (Mul (diff a x) b)
diff (Mul 2 (Var "x")) "x"
2*1+0*x
0+e
e+0
0*e
e*0
1*e
e*1
add
mul
Add
Mul
add (Num 0) b = b add a (Num 0) = a add a b = Add a b
mul (Num 0) b = Num 0 mul a (Num 0) = Num 0 mul (Num 1) b = b mul a (Num 1) = a mul a b = Mul a b
x = 1+2
> y = x*4
> x+y
18
data Command = Define Name Expr | Eval Expr command :: Parser Command command = (...)
main :: IO () main = do putStrLn "Welcome to the simple calculator!" repl [] repl :: [(Name,Integer)] -> IO () repl env = do putStr "> " s <- getLine case completeParse command s of Just (Define n e) -> repl ((n,eval env e):env) Just (Eval e) -> do print (eval env e) repl env _ -> do putStrLn "Syntax error!" repl env
2*x
*** Exception: undefined variable: x
D x 2*x*x+3*y
4*x
>