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:
data Expr = Val Int | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr
For instance, Add (Val 3) (Div (Val 4) (Val 2))
represents
,
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"