diff --git a/core/CCList.ml b/core/CCList.ml index b95942ed..ddb0fa5c 100644 --- a/core/CCList.ml +++ b/core/CCList.ml @@ -510,6 +510,39 @@ module Zipper = struct | _, [] -> raise Not_found end +(** {2 References on Lists} *) + +module Ref = struct + type 'a t = 'a list ref + + let push l x = l := x :: !l + + let pop l = match !l with + | [] -> None + | x::tail -> + l := tail; + Some x + + let pop_exn l = match !l with + | [] -> failwith "CCList.Ref.pop_exn" + | x::tail -> + l := tail; + x + + let create() = ref [] + + let clear l = l := [] + + let lift f l = f !l + + let push_list r l = + r := List.rev_append l !r + + (*$T + let l = Ref.create() in Ref.push l 1; Ref.push_list l [2;3]; !l = [3;2;1] + *) +end + (** {2 Monadic Operations} *) module type MONAD = sig type 'a t diff --git a/core/CCList.mli b/core/CCList.mli index a94820f5..2c885a51 100644 --- a/core/CCList.mli +++ b/core/CCList.mli @@ -225,6 +225,34 @@ module Zipper : sig @raise Not_found if the zipper is at an end *) end +(** {2 References on Lists} +@since NEXT_RELEASE *) + +module Ref : sig + type 'a t = 'a list ref + + val push : 'a t -> 'a -> unit + + val pop : 'a t -> 'a option + + val pop_exn : 'a t -> 'a + (** Unsafe version of {!pop}. + @raise Failure if the list is empty *) + + val create : unit -> 'a t + (** Create a new list reference *) + + val clear : _ t -> unit + (** Remove all elements *) + + val lift : ('a list -> 'b) -> 'a t -> 'b + (** Apply a list function to the content *) + + val push_list : 'a t -> 'a list -> unit + (** Add elements of the list at the beginning of the list ref. Elements + at the end of the list will be at the beginning of the list ref *) +end + (** {2 Monadic Operations} *) module type MONAD = sig type 'a t