92 lines
1.9 KiB
Markdown
92 lines
1.9 KiB
Markdown
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/recursivite-meme.png " width=512 height=auto /> </center>
|
|
|
|
### 5.1. Simple functions
|
|
To create a recursive function we have to use this structure
|
|
|
|
```Ocaml
|
|
(*normal function*)
|
|
# let f = expr -> 1) evaluate expr ; 2) create & link f to the result
|
|
|
|
(*recursiv function*)
|
|
# let rec f = expr -> 1) create f ; 2) evaluate expr ; 3) link f to the result
|
|
```
|
|
|
|
**Exmple with factorial function**
|
|
```Ocaml
|
|
# let rec fact = function
|
|
| 0 -> 1
|
|
| n -> n * fact(n-1)
|
|
|
|
# fact 4;;
|
|
-: int = 24
|
|
```
|
|

|
|
> ⚠️ CAML have a call stack limite (it will block with stack overflow if the limit is reach)
|
|
|
|
**Basic expression**
|
|
```Ocaml
|
|
let rec f params =
|
|
if stop condition then
|
|
stop expression
|
|
else
|
|
recursive expression
|
|
```
|
|
|
|
To write a recurvise function we need two things
|
|
1) There always is a stop case
|
|
2) The parameters of a recursive call are different then its parent call, and go towards the stop condition
|
|
|
|
### 5.2. Down
|
|
```Ocaml
|
|
# let rec countdown n =
|
|
if n < 0 then
|
|
()
|
|
else
|
|
begin
|
|
print_int n ;
|
|
print_newline();
|
|
countdown(n-1);
|
|
end;;
|
|
val countdown = int -> unit = ()
|
|
|
|
# countdown 3;;
|
|
3
|
|
2
|
|
1
|
|
- : unit = ()
|
|
```
|
|
Flowchart of CAML evaluation
|
|
```mermaid
|
|
flowchart LR
|
|
|
|
A[ctd 3] --> B[ctd 2] --> C[ctd 1] --> D[ctd 0] --> E[ctd -1] --> F[ ] --> E --> D --> C --> B --> A
|
|
```
|
|
> ctd is countdown
|
|
|
|
## 5.3. Several recursive calls
|
|
A function that have several recursive calls is defind like this
|
|
$$
|
|
Fn = {1 -> \text{if } n\eqslantless{1} \brace{Fn+1+Fn+2} }
|
|
$$
|
|
**Fibonacci functions**
|
|
```Ocaml
|
|
let rec fibonacci n =
|
|
if n = 0 then
|
|
0
|
|
else if n = 1 then
|
|
1
|
|
else
|
|
fibonacci(n-1) + fibonacci(n-2);;
|
|
|
|
let rec odd n =
|
|
if n = 0 then
|
|
false
|
|
else
|
|
even (n-1);;
|
|
|
|
let rec even n =
|
|
if n = 0 then
|
|
true
|
|
else
|
|
add (n-1);;
|
|
``` |