module type S = sig
  type elt
  type t
  type 'a map

  val empty : t
  val is_empty : t -> bool
  val mem : t -> elt -> bool
  val add : t -> elt -> t
  val singleton : elt -> t
  val remove : t -> elt -> t
  val union : t -> t -> t
  val inter : t -> t -> t
  val diff : t -> t -> t
  val compare : t -> t -> Ordering.t
  val equal : t -> t -> bool
  val is_subset : t -> of_:t -> bool
  val iter : t -> f:(elt -> unit) -> unit
  val map : t -> f:(elt -> elt) -> t
  val fold : t -> init:'a -> f:(elt -> 'a -> 'a) -> 'a
  val for_all : t -> f:(elt -> bool) -> bool
  val exists : t -> f:(elt -> bool) -> bool
  val filter : t -> f:(elt -> bool) -> t
  val partition : t -> f:(elt -> bool) -> t * t
  val cardinal : t -> int
  val min_elt : t -> elt option
  val max_elt : t -> elt option
  val choose : t -> elt option
  val choose_exn : t -> elt
  val split : t -> elt -> t * bool * t
  val of_list : elt list -> t
  val of_list_map : 'a list -> f:('a -> elt) -> t
  val to_list : t -> elt list
  val to_seq : t -> elt Seq.t

  (** Convert to a list and map every element. *)
  val to_list_map : t -> f:(elt -> 'a) -> 'a list

  val find : t -> f:(elt -> bool) -> elt option
  val union_all : t list -> t
  val union_map : 'a list -> f:('a -> t) -> t
  val to_dyn : t -> Dyn.t
  val of_keys : _ map -> t
  val to_map : t -> f:(elt -> 'a) -> 'a map
end
