sig
  module type S =
    sig
      type param
      type result
      val extend : (Hook.S.param -> Hook.S.result) -> unit
      val extend_once : (Hook.S.param -> Hook.S.result) -> unit
      val apply : Hook.S.param -> Hook.S.result
      val is_empty : unit -> bool
      val clear : unit -> unit
      val length : unit -> int
    end
  module type Comparable =
    sig
      type t
      val equal : Hook.Comparable.t -> Hook.Comparable.t -> bool
      val hash : Hook.Comparable.t -> int
      val compare : Hook.Comparable.t -> Hook.Comparable.t -> int
    end
  module type S_ordered =
    sig
      type param
      type result
      val apply : param -> result
      val is_empty : unit -> bool
      val clear : unit -> unit
      val length : unit -> int
      type key
      type id
      val register_key : Hook.S_ordered.key -> Hook.S_ordered.id
      val extend : Hook.S_ordered.id -> (param -> result) -> unit
      val extend_once : Hook.S_ordered.id -> (param -> result) -> unit
      val add_dependency : Hook.S_ordered.id -> Hook.S_ordered.id -> unit
    end
  module type Iter_hook =
    sig
      type param
      type result = unit
      val extend : (param -> result) -> unit
      val extend_once : (param -> result) -> unit
      val apply : param -> result
      val is_empty : unit -> bool
      val clear : unit -> unit
      val length : unit -> int
    end
  module Build :
    functor (P : sig type t end->
      sig
        type param = P.t
        type result = unit
        val extend : (param -> result) -> unit
        val extend_once : (param -> result) -> unit
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
      end
  module Make :
    functor () ->
      sig
        type param = unit
        type result = unit
        val extend : (param -> result) -> unit
        val extend_once : (param -> result) -> unit
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
      end
  module Fold :
    functor (P : sig type t end->
      sig
        type param = P.t
        type result = P.t
        val extend : (param -> result) -> unit
        val extend_once : (param -> result) -> unit
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
      end
  module Build_ordered :
    functor (P : sig module Id : Comparable type t end->
      sig
        type param = P.t
        type result = unit
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
        type key = P.Id.t
        type id
        val register_key : key -> id
        val extend : id -> (param -> result) -> unit
        val extend_once : id -> (param -> result) -> unit
        val add_dependency : id -> id -> unit
      end
  module Make_ordered :
    functor (P : sig module Id : Comparable end->
      sig
        type param = unit
        type result = unit
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
        type key = P.Id.t
        type id
        val register_key : key -> id
        val extend : id -> (param -> result) -> unit
        val extend_once : id -> (param -> result) -> unit
        val add_dependency : id -> id -> unit
      end
  module Fold_ordered :
    functor (P : sig module Id : Comparable type t end->
      sig
        type param = P.t
        type result = P.t
        val apply : param -> result
        val is_empty : unit -> bool
        val clear : unit -> unit
        val length : unit -> int
        type key = P.Id.t
        type id
        val register_key : key -> id
        val extend : id -> (param -> result) -> unit
        val extend_once : id -> (param -> result) -> unit
        val add_dependency : id -> id -> unit
      end
end