sig
  val mk : '-> '-> 'a * 'b
  val left : 'a * '-> 'a
  val right : 'a * '-> 'b
  val map : ('-> 'b) -> 'a * '-> 'b * 'b
  val map_left : ('-> 'c) -> 'a * '-> 'c * 'b
  val map_right : ('-> 'c) -> 'a * '-> 'a * 'c
  val apply : ('-> '-> 'c) -> 'a * '-> 'c
  val conj : bool * bool -> bool
  val disj : bool * bool -> bool
  val swap : 'a * '-> 'b * 'a
  val fold : ('-> '-> 'b) -> 'a * '-> '-> 'b
  val both : bool * bool -> bool
  val either : bool * bool -> bool
  module Make :
    functor (T : Utilsigs.BasicType) (S : Utilsigs.BasicType->
      sig
        type t = T.t * S.t
        val compare : t -> t -> int
        val equal : t -> t -> bool
        val hash : t -> int
        val to_string : t -> string
        val pp : Format.formatter -> t -> unit
      end
end