mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
big upgrade of RAL (random access lists)
This commit is contained in:
parent
490c72d5f8
commit
e580340403
2 changed files with 86 additions and 10 deletions
68
misc/RAL.ml
68
misc/RAL.ml
|
|
@ -33,6 +33,9 @@ type +'a tree =
|
|||
and +'a t = (int * 'a tree) list
|
||||
(** Functional array of complete trees *)
|
||||
|
||||
(* TODO: inline list's nodes
|
||||
TODO: encode "complete binary tree" into types *)
|
||||
|
||||
|
||||
(** {2 Functions on trees} *)
|
||||
|
||||
|
|
@ -62,6 +65,8 @@ let rec tree_update size t i v =match t, i with
|
|||
|
||||
let empty = []
|
||||
|
||||
let return x = [1, Leaf x]
|
||||
|
||||
let is_empty = function
|
||||
| [] -> true
|
||||
| _ -> false
|
||||
|
|
@ -95,24 +100,52 @@ let tl l = match l with
|
|||
let size' = size / 2 in
|
||||
(size', t1) :: (size', t2) :: l'
|
||||
|
||||
let front l = match l with
|
||||
| [] -> None
|
||||
| (_, Leaf x) :: tl -> Some (x, tl)
|
||||
| (size, Node (x, t1, t2)) :: l' ->
|
||||
let size' = size / 2 in
|
||||
Some (x, (size', t1) :: (size', t2) :: l')
|
||||
|
||||
let front_exn l = match l with
|
||||
| [] -> raise (Invalid_argument "RAL.front")
|
||||
| (_, Leaf x) :: tl -> x, tl
|
||||
| (size, Node (x, t1, t2)) :: l' ->
|
||||
let size' = size / 2 in
|
||||
x, (size', t1) :: (size', t2) :: l'
|
||||
|
||||
let rec _remove prefix l i =
|
||||
let x, l' = front_exn l in
|
||||
if i=0
|
||||
then List.fold_left (fun l x -> cons x l) l prefix
|
||||
else _remove (x::prefix) l' (i-1)
|
||||
|
||||
let remove l i = _remove [] l i
|
||||
|
||||
let rec _map_tree f t = match t with
|
||||
| Leaf x -> Leaf (f x)
|
||||
| Node (x, l, r) -> Node (f x, _map_tree f l, _map_tree f r)
|
||||
|
||||
let map f l = List.map (fun (i,t) -> i, _map_tree f t) l
|
||||
|
||||
let rec length l = match l with
|
||||
| [] -> 0
|
||||
| (size,_) :: l' -> size + length l'
|
||||
|
||||
let rec iter l f = match l with
|
||||
let rec iter f l = match l with
|
||||
| [] -> ()
|
||||
| (_, Leaf x) :: l' -> f x; iter l' f
|
||||
| (_, t) :: l' -> iter_tree t f; iter l' f
|
||||
| (_, Leaf x) :: l' -> f x; iter f l'
|
||||
| (_, t) :: l' -> iter_tree t f; iter f l'
|
||||
and iter_tree t f = match t with
|
||||
| Leaf x -> f x
|
||||
| Node (x, t1, t2) -> f x; iter_tree t1 f; iter_tree t2 f
|
||||
|
||||
let rec fold l acc f = match l with
|
||||
let rec fold f acc l = match l with
|
||||
| [] -> acc
|
||||
| (_, Leaf x) :: l' -> fold l' (f acc x) f
|
||||
| (_, Leaf x) :: l' -> fold f (f acc x) l'
|
||||
| (_, t) :: l' ->
|
||||
let acc' = fold_tree t acc f in
|
||||
fold l' acc' f
|
||||
fold f acc' l'
|
||||
and fold_tree t acc f = match t with
|
||||
| Leaf x -> f acc x
|
||||
| Node (x, t1, t2) ->
|
||||
|
|
@ -120,6 +153,27 @@ and fold_tree t acc f = match t with
|
|||
let acc = fold_tree t1 acc f in
|
||||
fold_tree t2 acc f
|
||||
|
||||
let rec fold_rev f acc l = match l with
|
||||
| [] -> acc
|
||||
| (_, Leaf x) :: l' -> f (fold f acc l') x
|
||||
| (_, t) :: l' ->
|
||||
let acc = fold_rev f acc l' in
|
||||
fold_tree_rev t acc f
|
||||
and fold_tree_rev t acc f = match t with
|
||||
| Leaf x -> f acc x
|
||||
| Node (x, t1, t2) ->
|
||||
let acc = fold_tree_rev t2 acc f in
|
||||
let acc = fold_tree_rev t1 acc f in
|
||||
f acc x
|
||||
|
||||
let append l1 l2 = fold_rev (fun l2 x -> cons x l2) l2 l1
|
||||
|
||||
let of_list l = List.fold_right cons l empty
|
||||
|
||||
let to_list l = List.rev (fold l [] (fun l x -> x :: l))
|
||||
let rec of_list_map f l = match l with
|
||||
| [] -> empty
|
||||
| x::l' ->
|
||||
let y = f x in
|
||||
cons y (of_list_map f l')
|
||||
|
||||
let to_list l = List.rev (fold (fun l x -> x :: l) [] l)
|
||||
|
|
|
|||
28
misc/RAL.mli
28
misc/RAL.mli
|
|
@ -43,13 +43,26 @@ val is_empty : _ t -> bool
|
|||
val cons : 'a -> 'a t -> 'a t
|
||||
(** Add an element at the front of the list *)
|
||||
|
||||
val return : 'a -> 'a t
|
||||
|
||||
val map : ('a -> 'b) -> 'a t -> 'b t
|
||||
(** Map on elements *)
|
||||
|
||||
val hd : 'a t -> 'a
|
||||
(** First element of the list, or @raise Invalid_argument if the list is empty *)
|
||||
(** First element of the list, or
|
||||
@raise Invalid_argument if the list is empty *)
|
||||
|
||||
val tl : 'a t -> 'a t
|
||||
(** Remove the first element from the list,
|
||||
or @raise Invalid_argument if the list is empty *)
|
||||
|
||||
val front : 'a t -> ('a * 'a t) option
|
||||
(** Remove and return the first element of the list *)
|
||||
|
||||
val front_exn : 'a t -> 'a * 'a t
|
||||
(** Unsafe version of {!front}.
|
||||
@raise Invalid_argument if the list is empty *)
|
||||
|
||||
val length : 'a t -> int
|
||||
(** Number of elements *)
|
||||
|
||||
|
|
@ -61,13 +74,22 @@ val set : 'a t -> int -> 'a -> 'a t
|
|||
(** [set l i v] sets the [i]-th element of the list to [v]. O(log(n)).
|
||||
@raise Invalid_argument if the list has less than [i+1] elements. *)
|
||||
|
||||
val iter : 'a t -> ('a -> unit) -> unit
|
||||
val remove : 'a t -> int -> 'a t
|
||||
(** [remove l i] removes the [i]-th element of [v].
|
||||
@raise Invalid_argument if the list has less than [i+1] elements. *)
|
||||
|
||||
val append : 'a t -> 'a t -> 'a t
|
||||
|
||||
val iter : ('a -> unit) -> 'a t -> unit
|
||||
(** Iterate on the list's elements *)
|
||||
|
||||
val fold : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b
|
||||
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
||||
(** Fold on the list's elements *)
|
||||
|
||||
val of_list : 'a list -> 'a t
|
||||
(** Convert a list to a RAL. {b Caution}: non tail-rec *)
|
||||
|
||||
val of_list_map : ('a -> 'b) -> 'a list -> 'b t
|
||||
(** Combination of {!of_list} and {!map} *)
|
||||
|
||||
val to_list : 'a t -> 'a list
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue