(* This is a lazy value which can be updated, implemented as a reference to a lazy value. The argument is a function which returns a new version of the function whose values we want to cache, and the return value is an update function. Each time the update function is called the value function will start returning different values. *) let cache (make_f : unit -> ('a -> 'b)) = let cache = ref (lazy (make_f ())) in let f x = (Lazy.force !cache) x and update () = cache := lazy (make_f ()) in f, update (* Example: let (f, update) = cache (fun () -> prerr_endline "make_f called"; let lines = Textfile.to_list "/proc/net/dev" in fun n -> List.nth lines n) # f 3;; make_f called eth0:2243284856 13022753 ... # f 3;; eth0:2243284856 13022753 ... # update ();; # f 3;; make_f called eth0:2243289284 13022773 ... # f 3;; eth0:2243289284 13022773 ... *) (* This function caches the function return values by cacheing them in a hashtbl. It also returns a clear function to reset the cache. *) let tablecache f = let table = Hashtbl.create 10 in let cached x = try Hashtbl.find table x with Not_found -> let value = f x in Hashtbl.add table x value; value in cached, (fun () -> Hashtbl.clear table)