We want to have a module to mainpulate and evaluate integer expressions with addition, substraction, multiplication and division operations. In order to do so, the following type is declared:
For instance, Add (Val 3) (Div (Val 4) (Val 2)) represents 3 + 4 / 2, which evaluates to 5.
Using the Expr type, define a function eval1 :: Expr -> Int that, given an expression, returns its evaluation. You can assume there will never be divisions by zero.
Using the Expr type, define a function eval2 :: Expr -> Maybe Int that, given an expression, returns its evaluationn as a Just value. In the case that some division by zero occurs, the result must be Nothing. You probably want to use the do notation over the Maybe a monad.
Using the Expr type, define a function eval3 :: Expr -> Either String Int that, given an expression, returns its evaluation as Right value. In the case that some division by zero occurs, the result must be Left "div0". You probably want to use the do notation over the Either a b monad.
Input
eval1 (Val 2) eval1 (Add (Val 2) (Val 3)) eval1 (Sub (Val 2) (Val 3)) eval1 (Div (Val 4) (Val 2)) eval1 (Mul (Add (Val 2) (Val 3)) (Sub (Val 2) (Val 3)))
Output
2 5 -1 2 -5
Input
eval2 (Val 2) eval2 (Add (Val 2) (Val 3)) eval2 (Sub (Val 2) (Val 3)) eval2 (Div (Val 4) (Val 2)) eval2 (Mul (Add (Val 2) (Val 3)) (Sub (Val 2) (Val 3))) eval2 (Div (Val 4) (Val 0)) eval2 (Add (Div (Val 4) (Val 0)) (Val 3)) eval2 (Add (Val 3) (Div (Val 4) (Val 0)))
Output
Just 2 Just 5 Just (-1) Just 2 Just (-5) Nothing Nothing Nothing
Input
eval3 (Val 2) eval3 (Add (Val 2) (Val 3)) eval3 (Sub (Val 2) (Val 3)) eval3 (Div (Val 4) (Val 2)) eval3 (Mul (Add (Val 2) (Val 3)) (Sub (Val 2) (Val 3))) eval3 (Div (Val 4) (Val 0)) eval3 (Add (Div (Val 4) (Val 0)) (Val 3)) eval3 (Add (Val 3) (Div (Val 4) (Val 0)))
Output
Right 2 Right 5 Right (-1) Right 2 Right (-5) Left "div0" Left "div0" Left "div0"