ocaml/stdlib/list.ml

111 lines
2.3 KiB
OCaml

(* List operations *)
let rec length = function
[] -> 0
| a::l -> 1 + length l
let hd = function
[] -> failwith "hd"
| a::l -> a
let tl = function
[] -> failwith "tl"
| a::l -> l
let rec nth l n =
match l with
[] -> failwith "nth"
| a::l -> if n <= 0 then a else nth l (n-1)
let rec rev_append accu = function
[] -> accu
| a::l -> rev_append (a :: accu) l
let rev l = rev_append [] l
let rec flatten = function
[] -> []
| l::r -> l @ flatten r
let rec map f = function
[] -> []
| a::l -> let r = f a in r :: map f l
(* let rec map f = function
[] -> []
| a::l -> f a :: map f l *)
let rec iter f = function
[] -> ()
| a::l -> f a; iter f l
let rec fold_left f accu l =
match l with
[] -> accu
| a::l -> fold_left f (f accu a) l
let rec fold_right f l accu =
match l with
[] -> accu
| a::l -> f a (fold_right f l accu)
let rec map2 f l1 l2 =
match (l1, l2) with
([], []) -> []
| (a1::l1, a2::l2) -> f a1 a2 :: map2 f l1 l2
| (_, _) -> invalid_arg "List.map2"
let rec iter2 f l1 l2 =
match (l1, l2) with
([], []) -> ()
| (a1::l1, a2::l2) -> f a1 a2; iter2 f l1 l2
| (_, _) -> invalid_arg "List.iter2"
let rec fold_left2 f accu l1 l2 =
match (l1, l2) with
([], []) -> accu
| (a1::l1, a2::l2) -> fold_left2 f (f accu a1 a2) l1 l2
| (_, _) -> invalid_arg "List.fold_left2"
let rec fold_right2 f l1 l2 accu =
match (l1, l2) with
([], []) -> accu
| (a1::l1, a2::l2) -> f a1 a2 (fold_right2 f l1 l2 accu)
| (_, _) -> invalid_arg "List.fold_right2"
let rec for_all p = function
[] -> true
| a::l -> p a & for_all p l
let rec exists p = function
[] -> false
| a::l -> p a or exists p l
let rec mem x = function
[] -> false
| a::l -> a = x or mem x l
let rec assoc x = function
[] -> raise Not_found
| (a,b)::l -> if a = x then b else assoc x l
let rec mem_assoc x = function
[] -> false
| (a,b)::l -> a = x or mem_assoc x l
let rec assq x = function
[] -> raise Not_found
| (a,b)::l -> if a == x then b else assq x l
let rec split = function
[] -> ([], [])
| (x,y)::l ->
let (rx, ry) = split l in (x::rx, y::ry)
let rec combine l1 l2 =
match (l1, l2) with
([], []) -> []
| (a1::l1, a2::l2) -> (a1, a2) :: combine l1 l2
| (_, _) -> invalid_arg "List.combine"