`type ('a, 'b) manual_cache = {`

1. `get : 'a -> 'b;`
2. `del : 'a -> unit;`
3. `enum : unit -> ('a * 'b) BatEnum.t;`

`}`
`val make_ht : gen:('a -> 'b) -> init_size:int -> ('a, 'b) manual_cache`

Make a manual cache backed by a hashtable. The generating function is passed with `~gen` and the initial size of the hashtable is `~init_size`. The hashtable uses the polymorphic `hash` and `(=)`.

`val make_map : gen:('a -> 'b) -> ('a, 'b) manual_cache`

Make a manual cache for function `~gen` backed by a Set.t. This set uses the polymorphic `(<)` for comparison, so `'a` should be properly comparable by it.

`type ('a, 'b) auto_cache = 'a -> 'b`

Automatically managed caches

This type of cache is more transparent than the `!manual_cache` above. It does not provide inspection of the caching structure, but guarantees bounded memory usage through some policy of discarding some entries.

Each auto-cache can have a different policy to decide which entry to discard.

`val lru_cache : gen:('a -> 'b) -> cap:int -> ('a, 'b) auto_cache`