From fdcba1122d443860b8f7fa4496b04f40e2d822e8 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Thu, 1 Oct 2015 18:54:17 +0200 Subject: [PATCH] add `CCKlist.memoize` for costly computations --- doc/intro.txt | 1 + src/core/CCFormat.mli | 4 ++-- src/iter/CCKList.ml | 30 ++++++++++++++++++++++++++++++ src/iter/CCKList.mli | 4 ++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/doc/intro.txt b/doc/intro.txt index 3b13b399..36fb49ce 100644 --- a/doc/intro.txt +++ b/doc/intro.txt @@ -72,6 +72,7 @@ CCFQueue CCFlatHashtbl CCHashSet CCHashTrie +CCImmutArray CCIntMap CCMixmap CCMixset diff --git a/src/core/CCFormat.mli b/src/core/CCFormat.mli index 6a4c46f6..818ed3c2 100644 --- a/src/core/CCFormat.mli +++ b/src/core/CCFormat.mli @@ -67,7 +67,7 @@ val stdout : t val stderr : t val sprintf : ('a, t, unit, string) format4 -> 'a - (** print into a string *) +(** print into a string *) val to_file : string -> ('a, t, unit, unit) format4 -> 'a - (** Print to the given file *) +(** Print to the given file *) diff --git a/src/iter/CCKList.ml b/src/iter/CCKList.ml index 4a55e967..b09d4dde 100644 --- a/src/iter/CCKList.ml +++ b/src/iter/CCKList.ml @@ -441,6 +441,36 @@ let sort_uniq ?(cmp=Pervasives.compare) l = let l = to_list l in uniq (fun x y -> cmp x y = 0) (of_list (List.sort cmp l)) +type 'a memoize = + | MemoThunk + | MemoSave of [`Nil | `Cons of 'a * 'a t] + +let rec memoize f = + let r = ref MemoThunk in + fun () -> match !r with + | MemoSave l -> l + | MemoThunk -> + let l = match f() with + | `Nil -> `Nil + | `Cons (x, tail) -> `Cons (x, memoize tail) + in + r := MemoSave l; + l + +(*$R + let printer = Q.Print.(list int) in + let gen () = + let rec l = let r = ref 0 in fun () -> incr r; `Cons (!r, l) in l + in + let l1 = gen () in + assert_equal ~printer [1;2;3;4] (take 4 l1 |> to_list); + assert_equal ~printer [5;6;7;8] (take 4 l1 |> to_list); + let l2 = gen () |> memoize in + assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); + assert_equal ~printer [1;2;3;4] (take 4 l2 |> to_list); +*) + + (** {2 Fair Combinations} *) let rec interleave a b () = match a() with diff --git a/src/iter/CCKList.mli b/src/iter/CCKList.mli index ef3ee73b..d785ec97 100644 --- a/src/iter/CCKList.mli +++ b/src/iter/CCKList.mli @@ -191,6 +191,10 @@ val sort_uniq : ?cmp:'a ord -> 'a t -> 'a t finite. O(n ln(n)) time and space. @since 0.3.3 *) +val memoize : 'a t -> 'a t +(** Avoid recomputations by caching intermediate results + @since NEXT_RELEASE *) + (** {2 Fair Combinations} *) val interleave : 'a t -> 'a t -> 'a t