sig
  val memoize :
    ?destruct:('-> unit) ->
    ?expire:[ `Keep_all | `Keep_one | `Lru of int ] -> ('-> 'b) -> '-> 'b
  val unit : (unit -> 'a) -> unit -> 'a
  module Lru :
    sig
      type ('k, 'v) t = ('k, 'v) Cache.Lru.t
      type ('a, 'b) memo = ('a, ('b, exn) Core.Std.Result.t) t
      val find : ('k, 'v) t -> '-> 'v option
      val add : ('k, 'v) t -> key:'-> data:'-> unit
      val remove : ('k, 'a) t -> '-> unit
      val clear : ('a, 'b) t -> unit
      val create : destruct:('-> unit) option -> int -> ('k, 'v) t
      val call_with_cache : cache:('a, 'b) memo -> ('-> 'b) -> '-> 'b
      val memoize :
        ?destruct:('-> unit) ->
        ('-> 'b) -> int -> ('a, 'b) memo * ('-> 'b)
    end
  module Keep_all :
    sig
      type ('k, 'v) t = ('k, 'v) Cache.Keep_all.t
      type ('a, 'b) memo = ('a, ('b, exn) Core.Std.Result.t) t
      val find : ('k, 'v) t -> '-> 'v option
      val add : ('k, 'v) t -> key:'-> data:'-> unit
      val remove : ('k, 'a) t -> '-> unit
      val clear : ('a, 'b) t -> unit
      val create : destruct:('-> unit) option -> ('k, 'v) t
      val call_with_cache : cache:('a, 'b) memo -> ('-> 'b) -> '-> 'b
      val memoize :
        ?destruct:('-> unit) -> ('-> 'b) -> ('a, 'b) memo * ('-> 'b)
    end
  module type Strategy =
    sig
      type 'a t
      type 'a with_init_args
      val cps_create : f:('a t -> 'b) -> 'b with_init_args
      val touch : 'a t -> '-> 'a list
      val remove : 'a t -> '-> unit
      val clear : 'a t -> unit
    end
  module type Store =
    sig
      type ('k, 'v) t
      type 'a with_init_args
      val cps_create : f:(('a, 'c) t -> 'b) -> 'b with_init_args
      val clear : ('k, 'v) t -> unit
      val replace : ('k, 'v) t -> key:'-> data:'-> unit
      val find : ('k, 'v) t -> '-> 'v option
      val data : ('a, 'v) t -> 'v list
      val remove : ('k, 'v) t -> '-> unit
    end
  module type S =
    sig
      type ('k, 'v) t
      type 'a with_init_args
      type ('a, 'b) memo = ('a, ('b, exn) Core.Std.Result.t) t
      val find : ('k, 'v) t -> '-> 'v option
      val add : ('k, 'v) t -> key:'-> data:'-> unit
      val remove : ('k, 'a) t -> '-> unit
      val clear : ('a, 'b) t -> unit
      val create : destruct:('-> unit) option -> ('k, 'v) t with_init_args
      val call_with_cache : cache:('a, 'b) memo -> ('-> 'b) -> '-> 'b
      val memoize :
        ?destruct:('-> unit) ->
        ('-> 'b) -> (('a, 'b) memo * ('-> 'b)) with_init_args
    end
  module Strategy :
    sig
      module Lru :
        sig
          type 'a t = 'Cache.Strategy.Lru.t
          type 'a with_init_args = int -> 'a
          val cps_create : f:('a t -> 'b) -> 'b with_init_args
          val touch : 'a t -> '-> 'a list
          val remove : 'a t -> '-> unit
          val clear : 'a t -> unit
        end
      module Keep_all :
        sig
          type 'a t = 'Cache.Strategy.Keep_all.t
          type 'a with_init_args = 'a
          val cps_create : f:('a t -> 'b) -> 'b with_init_args
          val touch : 'a t -> '-> 'a list
          val remove : 'a t -> '-> unit
          val clear : 'a t -> unit
        end
    end
  module Store :
    sig
      module Table :
        sig
          type ('k, 'v) t = ('k, 'v) Cache.Store.Table.t
          type 'a with_init_args = 'a
          val cps_create : f:(('a, 'c) t -> 'b) -> 'b with_init_args
          val clear : ('k, 'v) t -> unit
          val replace : ('k, 'v) t -> key:'-> data:'-> unit
          val find : ('k, 'v) t -> '-> 'v option
          val data : ('a, 'v) t -> 'v list
          val remove : ('k, 'v) t -> '-> unit
        end
    end
  module Make :
    functor (Strat : Strategy->
      functor (Store : Store->
        sig
          type ('k, 'v) t = ('k, 'v) Cache.Make(Strat)(Store).t
          type 'a with_init_args =
              'Store.with_init_args Strat.with_init_args
          type ('a, 'b) memo = ('a, ('b, exn) Core.Std.Result.t) t
          val find : ('k, 'v) t -> '-> 'v option
          val add : ('k, 'v) t -> key:'-> data:'-> unit
          val remove : ('k, 'a) t -> '-> unit
          val clear : ('a, 'b) t -> unit
          val create :
            destruct:('-> unit) option -> ('k, 'v) t with_init_args
          val call_with_cache : cache:('a, 'b) memo -> ('-> 'b) -> '-> 'b
          val memoize :
            ?destruct:('-> unit) ->
            ('-> 'b) -> (('a, 'b) memo * ('-> 'b)) with_init_args
        end
end