sig
  module type S =
    sig
      type t
      val append : Monoid.S.t -> Monoid.S.t -> Monoid.S.t
      val zero : Monoid.S.t
    end
  module Int :
    sig
      module Min : sig type t = int val append : t -> t -> t val zero : t end
      module Max : sig type t = int val append : t -> t -> t val zero : t end
      module Sum : sig type t = int val append : t -> t -> t val zero : t end
      module Product :
        sig type t = int val append : t -> t -> t val zero : t end
    end
  module All : sig type t = bool val append : t -> t -> t val zero : t end
  module Any : sig type t = bool val append : t -> t -> t val zero : t end
  module Dual :
    functor (M : S->
      sig type t = M.t val append : t -> t -> t val zero : t end
  module Endo :
    functor (T : sig type t end->
      sig type t = T.t -> T.t val append : t -> t -> t val zero : t end
  module Pair :
    functor (M1 : S) (M2 : S->
      sig type t = M1.t * M2.t val append : t -> t -> t val zero : t end
  module Opt :
    functor (S : Semigroup.S->
      sig type t = S.t option val append : t -> t -> t val zero : t end
end