module L04A where -- Week 4 -- Recursive data types. -- Part 1: The expression game -- dave@chalmers.se -- 2012-11-19 import Test.QuickCheck ------------------------------------------------------ data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving Eq instance Show Expr where show = showExpr -- (1+2)*4 ex1 = Mul (Add (Num 1) (Num 2)) (Num 4) -- 1 + 2 * 4 ex2 = Add (Num 1) (Mul (Num 2) (Num 4)) -- -5 + 2 * 4 eval :: Expr -> Integer eval (Num n) = n eval (Mul e1 e2) = eval e1 * eval e2 eval (Add e1 e2) = eval e1 + eval e2 -- show showExpr :: Expr -> String showExpr (Num n) = show n showExpr (Add e1 e2) = showExpr e1 ++ " + " ++ showExpr e2 showExpr (Mul e1 e2) = showFactor e1 ++ " * " ++ showFactor e2 showFactor (Add e1 e2) = "(" ++ showExpr (Add e1 e2) ++ ")" showFactor e = showExpr e -- ** range = 4 -- integer range level = fromInteger range -- level of difficulty (~ max expression size) rExpr :: Int -> Gen Expr rExpr s = frequency [(1,rNum),(s,rBin s)] where rNum = elements \$ map Num [-range..range] rBin s = do let s' = (s `div` 2) op <- elements [Mul,Add] e1 <- rExpr s' e2 <- rExpr s' return \$ op e1 e2 instance Arbitrary Expr where arbitrary = sized rExpr ------------------------------------------------------ main :: IO() main = do es <- sample' \$ rExpr level let e = es !! level putStrLn \$ "What is the value of " ++ show e ans <- getLine let v = show \$ eval e if (ans == v) then putStrLn "Correct!" else putStrLn \$ "Fail! Correct answer was: " ++ v main ---------------------------------------------------------------- -- * Reading Expressions