module L04B where 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 ) ex1 = Mul (Add (Num 1) (Num 2)) (Num 4) ex2 = Add (Num 1) (Mul (Num 2) (Num 4)) ex3 = Num 1 `Add` (Num 2 `Mul` Num 4) eval :: Expr -> Integer eval (Num m) = m eval (Add e f) = eval e + eval f eval (Mul e f) = eval e * eval f ----------------------------------------------------------------------- instance Show Expr where show = showExpr showExpr :: Expr -> String showExpr (Num n) = show n showExpr (Add a b) = showExpr a ++ "+" ++ showExpr b showExpr (Mul a b) = showFactor a ++ "*" ++ showFactor b showFactor :: Expr -> String showFactor (Add a b) = "(" ++ showExpr (Add a b) ++ ")" showFactor e = showExpr e ----------------------------------------------------------------------- instance Arbitrary Expr where arbitrary = sized arbExpr -- first attempt: arbExpr :: Int -> Gen Expr arbExpr s = frequency [ (1,genNum) , (s,genOp Add) , (s,genOp Mul) ] where genNum = do n <- arbitrary return (Num n) genOp op = do a <- arbExpr s' b <- arbExpr s' return (op a b) s' = s `div` 2 ------------------------------------------------------------------ questions :: IO ( ) questions = do rnd <- newStdGen let e = unGen arbitrary rnd 3 putStr ("What is " ++ show e ++ "? ") ans <- getLine let correctAns = eval e putStrLn (if ans == show correctAns -- read ans == correctAns then "Correct!" else "Wrong! Correct answer was: " ++ show correctAns) questions ----------------------------------------------------------------