diff --git a/core/CCRandom.ml b/core/CCRandom.ml index 86b1e6db..286fbbb5 100644 --- a/core/CCRandom.ml +++ b/core/CCRandom.ml @@ -41,6 +41,8 @@ let map f g st = f (g st) let (>|=) g f st = map f g st +let delay f st = f () st + let _choose_array a st = if Array.length a = 0 then invalid_arg "CCRandom.choose_array"; a.(Random.State.int st (Array.length a)) @@ -69,6 +71,8 @@ let replicate n g st = if n = 0 then acc else aux (g st :: acc) (n-1) in aux [] n +let list_seq l st = List.map (fun f -> f st) l + exception SplitFail let _split i st = diff --git a/core/CCRandom.mli b/core/CCRandom.mli index fcf00d42..77f28ab1 100644 --- a/core/CCRandom.mli +++ b/core/CCRandom.mli @@ -45,6 +45,21 @@ val map : ('a -> 'b) -> 'a t -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t +val delay : (unit -> 'a t) -> 'a t +(** Delay evaluation. Useful for side-effectful generators that + need some code to run for every call. + Example: + {[ + let gensym = let r = ref 0 in fun () -> incr r; !r ;; + + delay (fun () -> + let name = gensym() in + small_int >>= fun i -> return (name,i) + ) + ]} + @since NEXT_RELEASE +*) + val choose : 'a t list -> 'a option t (** Choose a generator within the list. *) @@ -59,6 +74,12 @@ val choose_return : 'a list -> 'a t @raise Invalid_argument if the list is empty *) val replicate : int -> 'a t -> 'a list t +(** [replace n g] makes a list of [n] elements which are all generated + randomly using [g] *) + +val list_seq : 'a t list -> 'a list t +(** Build random lists from lists of random generators + @since NEXT_RELEASE *) val small_int : int t