data Expr =
Const Int
| Add Expr Expr -- a+b
| Sub Expr Expr -- a-b
| Mul Expr Expr -- a*b
| Div Expr Expr -- a/b (ganzzahlige Division)
| Neg Expr -- -a
deriving (Eq, Show)
-- 1.1
{-
Hier gibt es eigentlich nicht viel zu erklären...
Division durch 0 ist nicht definiert und Negation entspricht der Multiplikation
mit (-1) .
-}
eval :: Expr -> Int
eval (Const n) = n
eval (Add e1 e2) = (eval e1)+(eval e2)
eval (Sub e1 e2) = (eval e1)-(eval e2)
eval (Mul e1 e2) = (eval e1)*(eval e2)
eval (Div e1 (Const 0)) = error "Division durch 0 nicht definiert"
eval (Div e1 e2) = (eval e1) `div` (eval e2)
eval (Neg e1) = eval (Mul (Const (-1)) e1)
-- 1.2
{-
Wir vereinbaren vorab:
Bei Negation und negativen Konstanten/Zahlen wird immer geklammert um klar zu machen,
dass eine negative Zahl gemeint ist bzw. um zu vermeiden, dass zwei Operatoren
nebeneinanderstehen. (Also z.B. nicht: 5 * -9, sondern 5 * (-9)
Ansonsten gelten die "normalen" Prioritäten wie Punkt- vor Strichrechnung und, dass
Ausdrücke von links nach rechts ausgewertet werden.
( 3*4/5*6 entspricht ((3*4)/5)*6 )
-}
getFormula :: Expr -> String
-- um den ganzen Term muss keine Klammer gemacht werde
-- immer wenn evtl. Punkt- vor Strichrechnung gilt, wird der "innere" Ausdruck
-- mit getKlammerFormula ausgwertet
getFormula (Const n) = if n<0 then "(" ++ show n ++ ")" else show n
getFormula (Add e1 e2) = getFormula e1 ++ "+" ++ getFormula e2
getFormula (Sub e1 e2) = getFormula e1 ++ "-" ++ getKlammerFormula e2
getFormula (Mul e1 e2) = getKlammerFormula e1 ++ "*" ++ getKlammerFormula e2