## Linear list
### Def
A linear data structure is a list where the elements must be treated sequentially.
$$ \lambda = $$
> $e_1$ is the rank of the value e. In linear list, we start at 0 because we don't use index list.
The linear list is evolutive, you can add or remove elements. Also, the linear list can be empty.
### List in CAML
```Ocaml
# [1 ; 2 ; 3];;
_: int list = [1, 2, 3]
```
> In CAML, all the element in the list have to be of the same type.
```Ocaml
# let l1 = ['H', 'i'];;
val l1 : char list = ['H'; 'i']
# let l2 = ['C'; 'a'; 'm'; 'l'];;
val l2 : char list = ['C' ; 'a' ;'m'; 'l']
# [l1; l2]
_: char list list : [['H'; 'i'] ; ['C' ; 'a' ;'m'; 'l']]
```
> The expression `char list` is the element type of the evaluation
```Ocaml
# ["H" ; 'i'];;
Error: string ≠ char
# [(function x -> x + 10); (function y -> 2*y)];;
_: (int -> int) list = [ ; ]
```
## The empty list
```Ocaml
# [];;
-: a list = []
```
## Recursive type
**`e::t` => adds the element e at the head (`e`) of the list tail (`f`)**
```Ocaml
# 1::[2; 3];;
_: int list = [1; 2; 3]
# 1::[];;
_: int list = [1]
```
**The constructor is right associative `e1::e2::e3::l` => `e1::(e2::(e3::l))`**
**Exemple :**
```Ocaml
# [1 ; 2; 3];;
_: int list = [1; 2; 3]
# 1::[2; 3];;
_: int list = [1; 2; 3]
# 1::2::[3];;
_: int list = [1; 2; 3]
# 1::2::3::[];;
_: int list = [1; 2; 3]
```
### Priority
```Ocaml
# 1 + 2::[];;
_: int list = [3]
# 1 < 2 :: [];;
Error: int ≠ int list
```
The priority is somewhere between the addition. To avoid any doubt in the code, we have to put parenthesis.
## Concatenation
```Ocaml
# let l1 = [1; 2] and l2 = [3; 4];;
val l1: int list = [1, 2]
val l2: int list = [3, 4]
# l1::l2;;
Error: int list ≠ int
#l1 @ l2;;
_: int list = [1 ; 2 ; 3; 4]
```
> The operator `@`is not constant
## List manipulation
### Traverse
Sequential traverse have two solution, first is the list is empty, then you stop. Else if the list is not empty, we extract the head and the tail, we treat the head and we traverse the trail (rec call)
```Ocaml
# let p = (1, 2);;
val p: int*int = (1,2)
# let (a, b) = p;;
val a: int = 1
val b: int = 2
# let l = [1; 2; 3];;
val l : int list = [1; 2; 3]
# let e::t = l;;
Warning: the pattern matching is not exhausitve
val e: int = 1
val t: int list = [2; 3]
# let rec length l =
if l = [] then 0
else
let e::t = l in
1 +. length t;;
Warning : pattern matching not exhaustive
val length: 'a list -> int =
# let rec length = function
| [] -> 0
| _::t -> 1 + length t;;
(* with this solution there is no warning *)
val length : 'a list -> int =
```
```mermaid
flowchart LR
A[l] --> |h::t| B[m < h ? ]
B --> C[m<-h]
B --> D[keep m]
A --> |"[]"| E[m]
C --> F[Continue the serach with t]
D --> F
```
## Build/modify a list
### Construction method
```Ocaml
# let rec what = function
0 -> []
| n -> n::what(n-1);;
val what : int -> int list =
# what 3;;
```
### Reverse
### Complexity