{- Setup -} data Expr = Number Integer | Plus Expr Expr | Negate Expr deriving Show eval :: Expr -> Integer eval (Number x) = x eval (Plus e1 e2) = eval e1 + eval e2 eval (Negate e) = - eval e ite True x y = x ite False x y = y data Nat = Zero | Plus1 Nat deriving Show nat0, nat1, nat2, nat3 :: Nat nat0 = Zero nat1 = Plus1 nat0 nat2 = Plus1 nat1 nat3 = Plus1 nat2 {- Exercise 1 -} conj :: Bool -> Bool -> Bool conj a b = undefined disj :: Bool -> Bool -> Bool disj a b = undefined impl :: Bool -> Bool -> Bool impl a b = undefined not2 :: Bool -> Bool not2 b = undefined {- Exercise 2 -} neg :: Expr -> Expr neg e = undefined normalize :: Expr -> Expr normalize e = undefined showNat :: Nat -> String showNat n = undefined nat :: Integer -> Nat nat n = undefined exprToNat :: Expr -> Nat exprToNat e = undefined {- Tests -} tests = do test "normalize (Plus (Number 2) (Negate (Number 1))) = Plus (Number 2) (Number (-1))" "Plus (Number 2) (Number (-1))" (normalize (Plus (Number 2) (Negate (Number 1)))) test "showNat Zero = \"0\"" "\"0\"" (showNat Zero) test "showNat nat3 = \"1+1+1\"" "\"1+1+1\"" (showNat nat3) test "nat 2 = Plus1 (Plus1 Zero)" "Plus1 (Plus1 Zero)" (nat 2) test "showNat (nat 5) = \"1+1+1+1+1\"" "\"1+1+1+1+1\"" (showNat (nat 5)) test "exprToNat (Plus (Number 1) (Number 1)) = nat2" "Plus1 (Plus1 Zero)" (exprToNat (Plus (Number 1) (Number 1))) test "exprToNat (Plus (Number 2) (Negate (Number 1))) = nat1" "Plus1 Zero" (exprToNat (Plus (Number 2) (Negate (Number 1)))) test "conj True False" "False" (conj True False) test "conj True True" "True" (conj True True) test "disj False True" "True" (disj False True) test "disj False False" "False" (disj False False) test "impl False True" "True" (impl False True) test "impl True False" "False" (impl True False) test "not2 True" "False" (not2 True) test name e c = do putStr ("*** " ++ name ++ ": ") if show c == e then putStrLn "OK" else putStrLn ("ERROR; expected '" ++ e ++ "', but found '" ++ show c ++ "'")