After writing my last post about Pattern matching in Scala, I was curious about how pattern matching was solved in other languages.

So in this post, I'll use the examples from the last blog post to compare how this would be solved in *Scala*, *Haskell*, *ML* and *OCaml*.

#### List example

The first example was to create a recursive function that prints a list of Integers as cons cells. So, let's take a look at how we would solve this using the different languages.

##### Scala

```
def pCons(list: List[Int]): String = list match {
case Nil => "nil"
case x::xs => "(" + x + "." + pCons(xs) + ")"
}
```

##### Haskell

```
pCons :: [Int] -> String
pCons [] = "nil"
pCons (x:xs) = "(" ++ show x ++ "." ++ pCons xs ++ ")"
```

##### ML

```
fun pCons [] = "nil"
| pCons (x::xs) = (concat ["(",(Int.toString x),".",(pCons xs),")"]);
```

##### OCaml

```
let rec p_cons = function
| [] -> "nil"
| x::xs -> "(" ^ string_of_int x ^ "." ^ p_cons xs ^ ")"
```

#### Language example

The other example defined a small language that contains 4 different types of expressions. Number, Sum, Product and Fun (function). Using this language, we can build different expressions.

Then we created 2 methods:

`prn`

- Takes an expression as an argument, then prints it in a Clojure-like way.`calc`

- Takes an expression as an argument, which it then evaluates.

Both these methods are solved using recursive functions and pattern matching.

#### Defining the language

First, let's define the language using case classes for Scala, and datatypes for Haskell, ML and OCaml.

##### Scala

```
abstract class Exp
case class Number(n: Int) extends Exp
case class Sum(e1: Exp, e2: Exp) extends Exp
case class Product(e1: Exp, e2: Exp) extends Exp
case class Fun(e: Exp) extends Exp
```

##### Haskell

```
data Exp = Number Int
| Sum Exp Exp
| Product Exp Exp
| Fun Exp
```

##### ML

```
datatype exp = Number of int
| Sum of exp * exp
| Product of exp * exp
| Fun of exp;
```

##### OCaml

```
type exp = Number of int
| Sum of exp * exp
| Product of exp * exp
| Fun of exp
```

#### Print function

Next is the `prn`

function, that prints a given expression in a Clojure-like way.

##### Scala

```
def prn(e: Exp): String = e match {
case Number(x) => x.toString
case Sum(e1, e2) => "(+ " + prn(e1) + " " + prn(e2) + ")"
case Product(e1, e2) => "(* " + prn(e1) + " " + prn(e2) + ")"
case Fun(e) => "(fn [] " + prn(e) + ")"
}
```

##### Haskell

```
prn :: Exp -> String
prn (Number x) = show x
prn (Sum e1 e2) = "(+ " ++ prn e1 ++ " " ++ prn e2 ++ ")"
prn (Product e1 e2) = "(* " ++ prn e1 ++ " " ++ prn e2 ++ ")"
prn (Fun e) = "(fn [] " ++ prn e ++ ")"
```

##### ML

```
fun prn (Number(x)) = (Int.toString x)
| prn (Sum(e1, e2)) = (concat ["(+ ", (prn e1), " ", (prn e2), ")"])
| prn (Product(e1, e2)) = (concat ["(* ", (prn e1), " ", (prn e2), ")"])
| prn (Fun(e)) = (concat ["(fn [] ", (prn e), ")"]);
```

##### OCaml

```
let rec prn = function
| Number(x) -> string_of_int x
| Sum(e1, e2) -> "(+ " ^ prn e1 ^ " " ^ prn e2 ^ ")"
| Product(e1, e2) -> "(* " ^ prn e1 ^ " " ^ prn e2 ^ ")"
| Fun(e) -> "(fn [] " ^ prn e ^ ")"
```

#### Calculate function

Last, is the `calc`

function that evaluates the expression given as an argument.

##### Scala

```
def calc(e: Exp): Int = e match {
case Number(x) => x
case Sum(e1, e2) => calc(e1) + calc(e2)
case Product(e1, e2) => calc(e1) * calc(e2)
case Fun(e) => calc(e)
```

##### Haskell

```
calc :: Exp -> Int
calc (Number x) = x
calc (Sum e1 e2) = calc e1 + calc e2
calc (Product e1 e2) = calc e1 * calc e2
calc (Fun e) = calc e
```

##### ML

```
fun calc (Number(x)) = x
| calc (Sum(e1, e2)) = (calc e1) + (calc e2)
| calc (Product(e1, e2)) = (calc e1) * (calc e2)
| calc (Fun(e)) = (calc e);
```

##### OCaml

```
let rec calc = function
| Number(x) -> x
| Sum(e1, e2) -> calc e1 + calc e2
| Product(e1, e2) -> calc e1 * calc e2
| Fun(e) -> calc e
```