## 3.1. The alternative 

<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/if-meme.png" width=auto height=400 /> </center>  

### The if structure
```Ocaml
if cond then expr1 else expr2
```
> ⚠️ `expr1` and `expr2` have to be the same type. `cond` is a `bool`

**For exemple**
```Ocaml
# if 1<2 then "higher" else "lower" ;;
-: string = "higher"
```

**Exercise : absolute program**
```Ocaml
# let abs(x) = 
	if x>0 then x
	else -x ;;;
val abs : int -> int <fun>
```

## 3.2. Exceptions


<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/exception-meme.png" width=auto height=400 /> </center>  

### Division by 0:
```Ocaml
# 1/0
Exception : Division by zero
```

### Failwith:
Failwith is a function that take a string argument (the reason) and return the error. That way, we can raise an error into our code
```Ocaml
# failwith;;
-: string -> a' = <fun>

# failwith "oops";;
Exception : Failwith "oops"
```

### invalid_arg:
Invalid_arg is a function that take a string argument (the reason) and return the error. That way, we can raison an error about an argument
```Ocaml
# invalid_arg "oops";
Exception: Invalid_argument "oops"

(*example*)
# let div a b = 
	if b = 0 then invalid_arg("div: b = 0")
	else a/b ;;;
val div int -> int -> int = <fun>
```

## 3.3. Filtering


<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/filter-meme.png " width=auto height=400 /> </center>  

### Explicit filtering

> Explicit means that you matches the value


**General syntax**

```Ocaml
match expr with pattern1 -> result1 | pattern2 -> result2 | ... | patternn -> resultn 
```
> All expressions and pattern must avec the same type

**Example**
```Ocaml
# let f x = match x with 
	0 -> 18
	| 1 -> 24
	| y ->  y * y;;

val f : int -> int = <fun>

# f 1;;
- : int = 24

# let g x = match x with
	0 -> 18
	| y -> y + y (*here will return a warning : unused case*)
	| 1 -> 24 ;;

val f : int -> int = <fun>
# f 1;;
- : int = 1

# let d x = match x with 
	0 -> 18;
	| 1 -> 24;;
	(* Warning = pattern matching not exhaustive *)
```

### Filtering several values

```Ocaml
# let and_ a b =
	match a with 
		true -> (match b with 
			true -> true
			| false -> false)
		| false -> false;;
```

> ⚠️ If you forgot the parentheses, Caml will belived the two `|false` belong to the same pattern matching

### Universal pattern 
```Ocaml
# let f x = match x with 
	0 -> 18
	| 1 -> 24
	| _ -> x*x ;;
```

### "Or" filter
```Ocaml
# let f x match x with 
	0 | 20 -> 18
	| 1 | 11 | 12 -> 24
	|_ -> x * x ;;
```

### Guarded filters
```Ocaml
# let sign x = match x with 
	0 -> 0
	| y when y < 0 -> -1
	| _ -> 1 
```

> `y when y<0` is an evaluation 
### Filtering and anonymous functions
```Ocaml
# let succ x = x +1;;
val succ: int -> int = <fun>

(* these two functions are equivalent *)

# let succ = function x -> x + 1;;
val succ: int -> int = <fun>
```

```Ocaml
# let f x = expr (*is equal to *) let f = function x -> expr
```
> ⚠️ Learn by heart

**Exemple with `avg` function**
```Ocaml
# let avg = function a -> function b -> (a+b)/2
val avg : int -> int -> int = <fun>
```
> 💭 We read that like "let avg the function that to a associate the function that to b associate a+b divided by two"

**For the match function**
```Ocaml
# let f x = match x with 
	| 0 -> 18
	| 1 -> 24
	| _ -> x*x ;;
# let f = function 
	| 0 -> 18
	| 1 -> 24
	| _ -> x * x;;
```

### Filtering several values
```Ocaml
# let and_p a b = match (a,b) with 
	| (true, true) -> true
	| _ -> false;;
val and_p : bool -> bool -> bool = <fun>

# let and_t = function 
	| (true, true) -> true
	| _ -> false
val and_t -> bool * bool = <fun>
```