Page 1

Page 2

# Modelling Arithmetic Expressions

• Imagine a program to help school children learn arithmetic:
• What is (1+2)*3? `8` Sorry, wrong answer!
• Expression like (1+2)*3 need to be treated as data in this program.
• We need to generate random expressions.
• We need show expressions to the user.
• We need to compute the values of expressions and compare with the answers that the user enters.
• Using strings might be possible, but will not make this easy...
Page 3
##### Modelling Arithmetic Expressions
• Use a datatype that reflects the structure of arithmetic expressions
• An expressions can be
• a number n
• a multiplication a*b
• where a and b are subexpressions
Page 4
##### Modelling Arithmetic Expressions
• As a Haskell data type
• ```data Expr = Num Integer
| Mul Expr Expr```
• Note: it's recursive.
• Examples:
2
`Num 2`
2+2
`Add (Num 2) (Num 2)`
(1+2)*3
`Mul (Add (Num 1) (Num 2)) (Num 3)`
1+2*3
`Add (Num 1) (Mul (Num 2) (Num 3))`
Page 5

# Example: Evaluation

• Define a function
• `eval :: Expr -> Integer`
• that computes the value of an expression.
• Example:
`eval (Add (Num 1) (Mul (Num 2) (Num 3)))`
==>
`7`
Page 6
##### Example: Evaluation
```eval :: Expr -> Integer
eval (Num n) = n
eval (Add a b) = eval a + eval b
eval (Mul a b) = eval a * eval b```
Page 7

# Showing Expressions

• ```showExpr :: Expr -> String
showExpr (Num n) = show n
showExpr (Add a b) = showEXpr a ++ "+" ++ showExpr b
showExpr (Mul a b) = showEXpr a ++ "*" ++ showExpr b```
• Will this work? Testing it:
• `showExpr (Mul (Num 1) (Add (Num 2) (Num 3)))` "1*2+3"
Page 8

• 1+(2+3)
• 1+(2*3)
• 1*(2+3)
Page 9

# Showing expressions with brackets

```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```
Page 10

# Making a Show instance

• ```instance Show Expr where
show = showExpr```
• Remove
`Show`
from the list of derived instances:
• data Expr = ... deriving (Eq,Show)
Page 11

# Generating arbitrary expressions

• First attempt
• ```rExpr_v1 :: Gen Expr
rExpr_v1 = oneof [rNum,rBin]
where
rNum = elements [Num n|n<-[1..10]]
rBin = do op <- elements [Add,Mul]
e1 <- rExpr_v1
e2 <- rExpr_v1
return (op e1 e2)
```
• But we need better control over the size of the generated expressions...
• ```rExpr :: Int -> Gen Expr
rExpr size = (...)
```
Page 12

# Completing the arithmetic quiz program

```main = do putStrLn "Welcome to the Arithmetic Quiz!"
forever quiz

quiz =
do e <- generate (rExpr 3)
putStr ("\n"++show e++" = ")
let correct = show (eval e)
then "Correct!"
else "Wrong! The correct answer is: "++correct)
```
Page 13

Page 14

# Summary

• Recursive datatypes can take many forms other than lists.
• Recursive datatypes can model languages (expressions, natural languages, programming languages).
• Functions working with recursive types are often recursive themselves (program structure follows data structure).
• When generating random elements in recursive datatype, think about the size.
Page 15

# Next time

• Today we defined
• `showExpr :: Expr -> String`
• Next time: how to write parsers:
• `readExpr :: String -> Expr`