Exercise set 6.


This is the last week of the haskell programming part of the course, and we are going to talk about testing. In particular, testing with tasty and quickcheck.

Credits

The exercises are based on "the mystery" assignment from the course advanced programming at the university of Copenhagen, which was formulated by Ken Friss Larsen.

Let it be

Consider the Haskell data type:

data Expression =
    Constant Integer
  | Variable Identifier
  | Operator Operator   Expression Expression
  | Let      Identifier Expression Expression
      deriving (Eq, Show, Read)

type Identifier = String

data Operator = Plus | Minus | Times
        deriving (Eq, Show, Read)

and the evaluator:

import qualified Data.Map.Strict as M
import Data.Map(Map)

type Env = Map String Integer

oper :: Operator -> (Integer -> Integer -> Integer)
oper Plus  = (+)
oper Minus = (-)
oper Times = (*)

eval :: Expression -> Env -> Either String Integer
eval (Constant n) env = return n
eval (Operator op x y) env = (oper op) <$> eval x env <*> eval y env
eval (Variable v) env = case M.lookup v env of
                     Nothing -> Left ("Unknown identifier: "++v)
                     Just val -> return val
eval (Let v e body) env = do
  val <- eval e env
  eval body $ M.insert v val env

evalTop e = eval e M.empty

simplify e =
  case e of
    Operator Plus  (Constant c1) (Constant c2) -> Constant(c1+c2)
    Operator Minus (Constant c1) (Constant c2) -> Constant(c1+c2)
    Operator Times (Constant c1) (Constant c2) -> Constant(c1*c2)
    Operator op e1 e2 ->
      Operator op (simplify e1) (simplify e2)
    Let v e body ->
      Let v (simplify e) (simplify body)
    _ -> e

Your tasks are as follows.