-- This is analogous to Arith2.java
import Prelude hiding (sum, product) -- because i want to use those names.
data Expr
= Literal Double
| Variable String
| Negated Expr
| Sum Expr Expr
| Difference Expr Expr
| Product Expr Expr
| Quotient Expr Expr
-- Smart "constant propagation" constructors
negated (Literal d) = Literal (0 - d)
negated (Negated x) = x
negated (Difference x y) = Difference y x
negated e = Negated e
sum (Literal d) (Literal e) = Literal (d+e)
sum (Literal 0) y = y
sum x (Literal 0) = x
sum x y = Sum x y
difference (Literal d) (Literal e) = Literal (d-e)
difference x (Literal 0) = x
difference x y = Difference x y
product (Literal d) (Literal e) = Literal (d*e)
product (Literal 0) _ = Literal 0
product (Literal 1) y = y
product _ (Literal 0) = Literal 0
product x (Literal 1) = x
product x y = Product x y
quotient (Literal d) (Literal e) = Literal (d/e)
quotient (Literal 0) _ = Literal 0
quotient x (Literal 1) = x
quotient x (Literal e) = product x (Literal (1/e))
quotient x y = Quotient x y
instance Show Expr -- how to print Exprs
where
showsPrec _ (Literal d) s = shows d s
showsPrec _ (Variable v) s = v ++ s
showsPrec _ (Negated x) s = "-" ++ shows x s
showsPrec _ (Sum x y) s = "(" ++ shows x ("+" ++ shows y (")" ++ s))
showsPrec _ (Difference x y) s = "(" ++ shows x ("-" ++ shows y (")" ++ s))
showsPrec _ (Product x y) s = "(" ++ shows x ("*" ++ shows y (")" ++ s))
showsPrec _ (Quotient x y) s = "(" ++ shows x ("/" ++ shows y (")" ++ s))
-- e is an environment of (variable name, value) pairs
value (Literal d) _ = d
value (Variable v) e = maybe 0 id (lookup v e)
value (Negated x) e = 0 - value x e
value (Sum x y) e = value x e + value y e
value (Difference x y) e = value x e - value y e
value (Product x y) e = value x e * value y e
value (Quotient x y) e = value x e / value y e
derivative (Literal _) _ = Literal 0
derivative (Variable v) w = Literal (if v == w then 1 else 0)
derivative (Negated x) w = negated (derivative x w)
derivative (Sum x y) w = sum (derivative x w) (derivative y w)
derivative (Difference x y) w = difference (derivative x w) (derivative y w)
derivative (Product x y) w = sum (product y (derivative x w))
(product x (derivative y w))
derivative (Quotient x y) w = quotient (difference
(product (derivative x w) y)
(product (derivative y w) x))
(product y y)
main = putStrLn (shows r (" == " ++ shows (value r e) "")) >>
putStrLn (shows (derivative r "X") "")
where x = Variable "X"
y = Variable "Y"
r = product (sum x y) (difference x y)
e = [("X",1.3),("Y",2.8)]
e = Product (Difference (Literal 1) (Literal 2))
(Sum (Literal 3) (Literal 4))