module L04A where -- Week 4 -- Recursive data types. The expression game -- dave@chalmers.se -- 2011-11-14 import Test.QuickCheck import Test.QuickCheck.Gen -- use quickCheck generators in other programs import System.Random ------------------------------------------------------------------ data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving Eq -- (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 ex3 = Num (-5) `Add` (Num 2 `Mul` Num 4) -- eval :: Expr -> Integer eval (Num n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (Mul 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 instance Show Expr where show = showExpr -- ** ----------------------------------------------------------------------- -- generators for expressions rExpr :: Int -> Gen Expr rExpr s = frequency [(1,rNum),(s,rOp)] where s' = s `div` 2 rNum = do n <- arbitrary return $ Num n rOp = do op <- elements [Add,Mul] e1 <- rExpr s' e2 <- rExpr s' return $ op e1 e2 instance Arbitrary Expr where arbitrary = sized rExpr ------------------------------------------------------------------ main :: IO ( ) main = do rnd <- newStdGen let e = unGen (rExpr 3) rnd 3 putStrLn $ "What is the value of " ++ show e ans <- getLine let v = eval e if (ans == show v) then putStrLn "Correct!" else putStrLn $ "Fail! Correct answer was: " ++ show v main ---------------------------------------------------------------- -- * Reading Expressions