sig
  module type MONOID =
    sig
      type t
      val empty : CCCat.MONOID.t
      val append : CCCat.MONOID.t -> CCCat.MONOID.t -> CCCat.MONOID.t
    end
  module type FUNCTOR =
    sig
      type +'a t
      val map : ('-> 'b) -> 'CCCat.FUNCTOR.t -> 'CCCat.FUNCTOR.t
    end
  module type APPLICATIVE =
    sig
      type +'a t
      val map : ('-> 'b) -> 'a t -> 'b t
      val pure : '-> 'CCCat.APPLICATIVE.t
      val ( <*> ) :
        ('-> 'b) CCCat.APPLICATIVE.t ->
        'CCCat.APPLICATIVE.t -> 'CCCat.APPLICATIVE.t
    end
  module type MONAD_BARE =
    sig
      type +'a t
      val return : '-> 'CCCat.MONAD_BARE.t
      val ( >>= ) :
        'CCCat.MONAD_BARE.t ->
        ('-> 'CCCat.MONAD_BARE.t) -> 'CCCat.MONAD_BARE.t
    end
  module type MONAD =
    sig
      type +'a t
      val return : '-> 'a t
      val ( >>= ) : 'a t -> ('-> 'b t) -> 'b t
      val map : ('-> 'b) -> 'a t -> 'b t
      val pure : '-> 'a t
      val ( <*> ) : ('-> 'b) t -> 'a t -> 'b t
    end
  module type MONAD_TRANSFORMER =
    sig
      type +'a t
      val return : '-> 'a t
      val ( >>= ) : 'a t -> ('-> 'b t) -> 'b t
      val map : ('-> 'b) -> 'a t -> 'b t
      val pure : '-> 'a t
      val ( <*> ) : ('-> 'b) t -> 'a t -> 'b t
      module M : MONAD
      val lift : 'M.t -> 'a t
    end
  type 'a sequence = ('-> unit) -> unit
  module type FOLDABLE =
    sig type 'a t val to_seq : 'CCCat.FOLDABLE.t -> 'CCCat.sequence end
  module type TRAVERSE =
    functor (M : MONAD->
      sig
        type +'a t
        val sequence_m : 'M.t CCCat.TRAVERSE.t -> 'CCCat.TRAVERSE.t M.t
        val fold_m :
          ('-> '-> 'M.t) -> '-> 'CCCat.TRAVERSE.t -> 'M.t
        val map_m :
          ('-> 'M.t) -> 'CCCat.TRAVERSE.t -> 'CCCat.TRAVERSE.t M.t
      end
  module type FREE_MONAD =
    sig
      module F : FUNCTOR
      type 'a t = Return of '| Roll of 'CCCat.FREE_MONAD.t F.t
      val return : '-> 'a t
      val ( >>= ) : 'a t -> ('-> 'b t) -> 'b t
      val map : ('-> 'b) -> 'a t -> 'b t
      val pure : '-> 'a t
      val ( <*> ) : ('-> 'b) t -> 'a t -> 'b t
      val inj : 'F.t -> 'CCCat.FREE_MONAD.t
    end
  module WrapMonad :
    functor (M : MONAD_BARE->
      sig
        type 'a t = 'M.t
        val return : '-> 'a t
        val ( >>= ) : 'a t -> ('-> 'b t) -> 'b t
        val map : ('-> 'b) -> 'a t -> 'b t
        val pure : '-> 'a t
        val ( <*> ) : ('-> 'b) t -> 'a t -> 'b t
      end
  module MakeFree :
    functor (F : FUNCTOR->
      sig
        module F :
          sig type 'a t = 'F.t val map : ('-> 'b) -> 'a t -> 'b t end
        type 'a t = Return of '| Roll of 'a t F.t
        val return : '-> 'a t
        val ( >>= ) : 'a t -> ('-> 'b t) -> 'b t
        val map : ('-> 'b) -> 'a t -> 'b t
        val pure : '-> 'a t
        val ( <*> ) : ('-> 'b) t -> 'a t -> 'b t
        val inj : 'F.t -> 'a t
      end
  module MakeFreeFold :
    functor
      (FM : FREE_MONAD) (Fold : sig
                                  type 'a t = 'FM.F.t
                                  val to_seq : 'a t -> 'a sequence
                                end->
      sig type 'a t = 'FM.t val to_seq : 'a t -> 'a sequence end
end