- 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...

- Use a datatype that reflects the structure of arithmetic expressions
- An expressions can be
- a number
`n` - an addition
`a`+`b` - a multiplication
`a`*`b`

- a number
- where
`a`and`b`are subexpressions

- Source code: ArithmeticQuiz.hs.

- As a Haskell data type
**data****Expr****=****Num****Integer****|****Add****Expr****Expr****|****Mul****Expr****Expr**- Note: it's
*recursive*.

- Examples:
Expression Haskell representation 2 **Num**22+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))

- Define a function
`eval`**::****Expr****->****Integer**

- that computes the value of an expression.
- Example: ==>
`eval`(**Add**(**Num**1) (**Mul**(**Num**2) (**Num**3)))`7`

eval::Expr->Integereval(Numn)=neval(Addab)=evala+evalbeval(Mulab)=evala*evalb

`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"

- 1+(2+3)
- 1+(2*3)
- 1*(2+3)

showExpr::Expr->StringshowExpr(Numn)=shownshowExpr(Addab)=showExpra++"+"++showExprbshowExpr(Mulab)=showFactora++"*"++showFactorbshowFactor::Expr->StringshowFactor(Addab)="("++showExpr(Addab)++")"showFactore=showExpre

**instance****Show****Expr****where**`show`**=**`showExpr`- Remove from the list of derived instances:
**Show** **data****Expr**= ...**deriving**(**Eq**~~,Show~~)

- 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`**=**(`...`)

main=doputStrLn"Welcome to the Arithmetic Quiz!"foreverquizquiz=doe<-generate(rExpr3)putStr("\n"++showe++" = ")answer<-getLineletcorrect=show(evale)putStrLn(ifanswer==correctthen"Correct!"else"Wrong! The correct answer is: "++correct)

- How about expressions with variables in them?
- See separate slides.

- 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*.

- Today we defined
`showExpr`**::****Expr****->****String**

- Next time: how to write
*parsers*:`readExpr`**::****String****->****Expr**