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