import Test.QuickCheck -- Data type for arithmetic expressions data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving (Eq) ex1 = Num 2 ex2 = Add (Num 2) (Num 2) ex3 = Mul (Add (Num 1) (Num 2)) (Num 3) ex4 = Add (Num 1) (Mul (Num 2) (Num 3)) -- Example expressions: 2, 2+2, (1+2)*3, 1+2*3 -- What's the difference between 17 and `Num 17` ? -- Quiz: `eval e` gives the value of the expression `e` eval :: Expr -> Integer eval (Num n) = n eval (Add a b) = eval a + eval b eval (Mul a b) = eval a * eval b -- socrative.com -> student login -> room: FP15 -- `showExpr e` shows the expression `e` as a string showExpr :: Expr -> String showExpr (Num n) = show n showExpr (Add a b) = showExpr a ++ "+" ++ showExpr b showExpr (Mul a b) = showFactor a ++ "*" ++ showFactor b -- showExpr (Mul (Num 1) (Add (Num 2) (Num 3))) showFactor :: Expr -> String showFactor e@(Add _ _) = "(" ++ showExpr e ++ ")" showFactor e = showExpr e -- Quiz: Which brackets are necessary? -- -- 1+(2+3) NO -- 1+(2*3) NO -- 1*(2+3) YES -- 1*(2*3) NO instance Show Expr where show = showExpr genExpr :: Int -> Gen Expr genExpr s = frequency [ (1, do n <- arbitrary return (Num n) ) , (s, do a <- genExpr (s `div` 2) b <- genExpr (s `div` 2) return (Add a b) ) , (s, do a <- genExpr (s `div` 2) b <- genExpr (s `div` 2) return (Mul a b) ) ] instance Arbitrary Expr where arbitrary = sized genExpr -- Define questions questions :: IO () questions = do e <- generate $ genExpr 5 putStr ("What is " ++ show e ++ "? ") ans <- getLine if ans == show (eval e) then putStrLn "Right!" else putStrLn "Wrong!" questions -- Fix "read: no parse"