diff --git a/src/data/CCRAL.ml b/src/data/CCRAL.ml index fcdc13b5..c2703eed 100644 --- a/src/data/CCRAL.ml +++ b/src/data/CCRAL.ml @@ -157,6 +157,15 @@ and fold_tree_rev t acc f = match t with let acc = fold_tree_rev t1 acc f in f acc x +let rev l = fold (fun acc x -> cons x acc) empty l + +(*$Q + Q.(list small_int) (fun l -> \ + let l = of_list l in rev (rev l) = l) + Q.(list small_int) (fun l -> \ + let l1 = of_list l in length l1 = List.length l) +*) + let append l1 l2 = fold_rev (fun l2 x -> cons x l2) l2 l1 (*$Q & ~small:(CCPair.merge (CCFun.compose_binop List.length (+))) @@ -191,6 +200,19 @@ let flatten l = fold_rev (fun acc l -> append l acc) empty l of_list [1;2;3;] *) +let app funs l = + fold_rev + (fun acc f -> + fold_rev + (fun acc x -> cons (f x) acc) + acc l + ) empty funs + +(*$T + app (of_list [(+) 2; ( * ) 10]) (of_list [1;10]) |> to_list = \ + [3; 12; 10; 100] +*) + (** {2 Conversions} *) type 'a sequence = ('a -> unit) -> unit @@ -211,15 +233,29 @@ let to_list l = fold_rev (fun acc x -> x :: acc) [] l Q.(list int) (fun l -> to_list (of_list l) = l) *) +let of_seq s = + let l = ref empty in + s (fun x -> l := cons x !l); + rev !l + let add_seq l s = let l1 = ref empty in s (fun x -> l1 := cons x !l1); - fold_rev (fun acc x -> cons x acc) l !l1 - -let of_seq s = add_seq empty s + fold (fun acc x -> cons x acc) l !l1 let to_seq l yield = iter yield l +(*$Q & ~small:List.length + Q.(list small_int) (fun l -> \ + of_list l |> to_seq |> Sequence.to_list = l) + Q.(list small_int) (fun l -> \ + Sequence.of_list l |> of_seq |> to_list = l) +*) + +(*$T + add_seq (of_list [3;4]) (Sequence.of_list [1;2]) |> to_list = [1;2;3;4] +*) + let rec gen_iter_ f g = match g() with | None -> () | Some x -> f x; gen_iter_ f g @@ -227,7 +263,7 @@ let rec gen_iter_ f g = match g() with let add_gen l g = let l1 = ref empty in gen_iter_ (fun x -> l1 := cons x !l1) g; - fold_rev (fun acc x -> cons x acc) l !l1 + fold (fun acc x -> cons x acc) l !l1 let of_gen g = add_gen empty g @@ -251,8 +287,10 @@ let to_gen l = in next -(*$Q - Q.(list int) (fun l -> of_list l |> to_gen |> Gen.to_list = l) +(*$Q & ~small:List.length + Q.(list small_int) (fun l -> of_list l |> to_gen |> Gen.to_list = l) + Q.(list small_int) (fun l -> \ + Gen.of_list l |> of_gen |> to_list = l) *) let rec of_list_map f l = match l with @@ -261,6 +299,16 @@ let rec of_list_map f l = match l with let y = f x in cons y (of_list_map f l') +(** {2 Infix} *) + +module Infix = struct + let (>>=) l f = flat_map f l + let (>|=) l f = map f l + let (<*>) = app +end + +include Infix + (** {2 IO} *) type 'a printer = Format.formatter -> 'a -> unit diff --git a/src/data/CCRAL.mli b/src/data/CCRAL.mli index 95c790ae..5c52422e 100644 --- a/src/data/CCRAL.mli +++ b/src/data/CCRAL.mli @@ -72,6 +72,8 @@ val flat_map : ('a -> 'b t) -> 'a t -> 'b t val flatten : 'a t t -> 'a t +val app : ('a -> 'b) t -> 'a t -> 'b t + val iter : ('a -> unit) -> 'a t -> unit (** Iterate on the list's elements *) @@ -81,6 +83,9 @@ val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b val fold_rev : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b (** Fold on the list's elements, in reverse order (starting from the tail) *) +val rev : 'a t -> 'a t +(** Reverse the list *) + (** {2 Conversions} *) type 'a sequence = ('a -> unit) -> unit @@ -108,6 +113,16 @@ val of_gen : 'a gen -> 'a t val to_gen : 'a t -> 'a gen +(** {2 Infix} *) + +module Infix : sig + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + val (>|=) : 'a t -> ('a -> 'b) -> 'b t + val (<*>) : ('a -> 'b) t -> 'a t -> 'b t +end + +include module type of Infix + (** {2 IO} *) type 'a printer = Format.formatter -> 'a -> unit