# 5 - Pattern Matching

Today we cover pattern matching, one of Scala's most powerful features.

You can find today's contents here.

## Practice

Let us have a simple hierarchy for dealing with mathematical expressions:

```trait Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr```
1. Write a simple function that uses pattern matching and converts an `Expr` to a human readable String, e.g. `1 + 2`:
`def show(e: Expr): String `
2. Add a new case class for products, call it `Prod`.
Modify your function to show the correct String representation, with the correct precedence shown by parentheses.
Try to minimize the number of parentheses.
For example `Sum(Prod(Number(2), Number(1)), Number(3)).show` should return `“2 * 1 + 3”`.
But`Prod(Sum(Number(2), Number(1)), Number(3)).show` should return `“(2 + 1) * 3”`.
3. Let's complicate this a bit.
Create a new Case class for variables, call it `Var` which takes a String as a parameter.
This will denote a variable in a mathematical expression.
Incorporate this into the `show` function you have just created.
4. We now want to evaluate a mathematical expression composed of numbers, sums, products and variables.
Use pattern matching and write a method in Expr
` def eval(vars: Map[String,Int]): Int `

which returns the numerical value of the mathematical expression.
The `vars` parameter denotes all the variable name-value associations so you could replace `Var`s with their corresponding numerical value.
If a variable cannot be found in the map, consider it to be 0.

5. (Challenge) Now the hard stuff. Write a function which converts a mathematical expression given as a String to an Expr
• start small: parse a number first, then variables, then sums, then products
• parse parentheses - create an auxiliary function which determines the substring in between two corresponding parentheses, then call `eval` recursively
• evaluate some mathematical expressions! 