sig
  module type Monad =
    sig
      type 'a t
      val return : '-> 'GapiMonad.Monad.t
      val bind :
        'GapiMonad.Monad.t ->
        ('-> 'GapiMonad.Monad.t) -> 'GapiMonad.Monad.t
    end
  module type MonadCombinators =
    sig
      type 'a m
      module Infix :
        sig
          val ( >>= ) :
            'GapiMonad.MonadCombinators.m ->
            ('-> 'GapiMonad.MonadCombinators.m) ->
            'GapiMonad.MonadCombinators.m
          val ( >> ) :
            'GapiMonad.MonadCombinators.m ->
            'GapiMonad.MonadCombinators.m ->
            'GapiMonad.MonadCombinators.m
        end
      val join :
        'GapiMonad.MonadCombinators.m GapiMonad.MonadCombinators.m ->
        'GapiMonad.MonadCombinators.m
      val liftM :
        ('-> 'b) ->
        'GapiMonad.MonadCombinators.m -> 'GapiMonad.MonadCombinators.m
      val liftM2 :
        ('-> '-> 'GapiMonad.MonadCombinators.m) ->
        'GapiMonad.MonadCombinators.m ->
        'GapiMonad.MonadCombinators.m -> 'GapiMonad.MonadCombinators.m
      val fmap :
        ('-> 'b) ->
        'GapiMonad.MonadCombinators.m -> 'GapiMonad.MonadCombinators.m
      val sequence :
        'GapiMonad.MonadCombinators.m list ->
        'a list GapiMonad.MonadCombinators.m
      val sequence_ :
        'GapiMonad.MonadCombinators.m list ->
        unit GapiMonad.MonadCombinators.m
      val mapM :
        ('-> 'GapiMonad.MonadCombinators.m) ->
        'a list -> 'b list GapiMonad.MonadCombinators.m
      val mapM_ :
        ('-> 'GapiMonad.MonadCombinators.m) ->
        'a list -> unit GapiMonad.MonadCombinators.m
      val foldM :
        ('-> '-> 'GapiMonad.MonadCombinators.m) ->
        '-> 'b list -> 'GapiMonad.MonadCombinators.m
    end
  module MakeMonadCombinators :
    functor (M : Monad->
      sig
        type 'a m = 'M.t
        module Infix :
          sig
            val ( >>= ) : 'a m -> ('-> 'b m) -> 'b m
            val ( >> ) : 'a m -> 'b m -> 'b m
          end
        val join : 'a m m -> 'a m
        val liftM : ('-> 'b) -> 'a m -> 'b m
        val liftM2 : ('-> '-> 'c m) -> 'a m -> 'b m -> 'c m
        val fmap : ('-> 'b) -> 'a m -> 'b m
        val sequence : 'a m list -> 'a list m
        val sequence_ : 'a m list -> unit m
        val mapM : ('-> 'b m) -> 'a list -> 'b list m
        val mapM_ : ('-> 'b m) -> 'a list -> unit m
        val foldM : ('-> '-> 'a m) -> '-> 'b list -> 'a m
      end
  module type StateMonad =
    sig
      type 'a t
      val return : '-> 'a t
      val bind : 'a t -> ('-> 'b t) -> 'b t
      val get : '-> 'a * 'a
      val put : '-> '-> unit * 'a
    end
  module MakeStateMonad :
    functor (T : sig type s end->
      sig
        type 'a t = T.s -> 'a * T.s
        val return : '-> 'a t
        val bind : 'a t -> ('-> 'b t) -> 'b t
        val get : '-> 'a * 'a
        val put : '-> '-> unit * 'a
      end
  module SessionM :
    sig
      type 'a t =
          GapiConversation.Session.t -> 'a * GapiConversation.Session.t
      val return : '-> 'a t
      val bind : 'a t -> ('-> 'b t) -> 'b t
      val get : '-> 'a * 'a
      val put : '-> '-> unit * 'a
      type 'a m = 'a t
      module Infix :
        sig
          val ( >>= ) : 'a m -> ('-> 'b m) -> 'b m
          val ( >> ) : 'a m -> 'b m -> 'b m
        end
      val join : 'a m m -> 'a m
      val liftM : ('-> 'b) -> 'a m -> 'b m
      val liftM2 : ('-> '-> 'c m) -> 'a m -> 'b m -> 'c m
      val fmap : ('-> 'b) -> 'a m -> 'b m
      val sequence : 'a m list -> 'a list m
      val sequence_ : 'a m list -> unit m
      val mapM : ('-> 'b m) -> 'a list -> 'b list m
      val mapM_ : ('-> 'b m) -> 'a list -> unit m
      val foldM : ('-> '-> 'a m) -> '-> 'b list -> 'a m
    end
  module type ListMonad =
    sig
      type 'a t = 'a list
      val return : '-> 'a t
      val bind : 'a t -> ('-> 'b t) -> 'b t
      val mzero : 'a t
      val mplus : 'a t -> 'a t -> 'a t
      val guard : bool -> unit t
    end
  module ListM :
    sig
      type 'a t = 'a list
      val return : '-> 'a t
      val bind : 'a t -> ('-> 'b t) -> 'b t
      val mzero : 'a t
      val mplus : 'a t -> 'a t -> 'a t
      val guard : bool -> unit t
      type 'a m = 'a t
      module Infix :
        sig
          val ( >>= ) : 'a m -> ('-> 'b m) -> 'b m
          val ( >> ) : 'a m -> 'b m -> 'b m
        end
      val join : 'a m m -> 'a m
      val liftM : ('-> 'b) -> 'a m -> 'b m
      val liftM2 : ('-> '-> 'c m) -> 'a m -> 'b m -> 'c m
      val fmap : ('-> 'b) -> 'a m -> 'b m
      val sequence : 'a m list -> 'a list m
      val sequence_ : 'a m list -> unit m
      val mapM : ('-> 'b m) -> 'a list -> 'b list m
      val mapM_ : ('-> 'b m) -> 'a list -> unit m
      val foldM : ('-> '-> 'a m) -> '-> 'b list -> 'a m
    end
end