sig
  exception InvalidEndpoint
  type _0
  type (+'a, -'b) st
  type et = (Session._0, Session._0) Session.st
  type 'a it = ('a, Session._0) Session.st
  type 'a ot = (Session._0, 'a) Session.st
  type (+'a, +'b) seq
  type ('a, 'b) choice = [ `False of '| `True of 'a ]
  module Bare :
    sig
      val create :
        ?name:string -> unit -> ('a, 'b) Session.st * ('b, 'a) Session.st
      val close : Session.et -> unit
      val send :
        '-> ('m * ('a, 'b) Session.st) Session.ot -> ('b, 'a) Session.st
      val receive :
        ('m * ('a, 'b) Session.st) Session.it -> 'm * ('a, 'b) Session.st
      val select :
        (('a, 'b) Session.st -> 'm) -> 'Session.ot -> ('b, 'a) Session.st
      val select_true :
        [> `True of ('a, 'b) Session.st ] Session.ot -> ('b, 'a) Session.st
      val select_false :
        [> `False of ('a, 'b) Session.st ] Session.ot -> ('b, 'a) Session.st
      val branch : ([>  ] as 'm) Session.it -> 'm
      val is_valid : ('a, 'b) Session.st -> bool
      val acquire : ('a, 'b) Session.st -> ('a, 'b) Session.st
      val try_acquire : ('a, 'b) Session.st -> ('a, 'b) Session.st option
      val same_session : ('a, 'b) Session.st -> ('c, 'd) Session.st -> bool
      val string_of_endpoint : ('a, 'b) Session.st -> string
      val ( @= ) :
        (('a, 'b) Session.st -> 'm * Session.et) ->
        ((('a, 'b) Session.st, ('c, 'd) Session.st) Session.seq,
         (('b, 'a) Session.st, ('d, 'c) Session.st) Session.seq)
        Session.st -> 'm * ('c, 'd) Session.st
      val ( @> ) :
        (('a, 'b) Session.st -> Session.et) ->
        ((('a, 'b) Session.st, ('c, 'd) Session.st) Session.seq,
         (('b, 'a) Session.st, ('d, 'c) Session.st) Session.seq)
        Session.st -> ('c, 'd) Session.st
    end
  module Monadic :
    sig
      type ('t0, 't1, 'a) t
      val return : '-> ('t0, 't0, 'm) Session.Monadic.t
      val ( >>= ) :
        ('t0, 't1, 'a) Session.Monadic.t ->
        ('-> ('t1, 't2, 'b) Session.Monadic.t) ->
        ('t0, 't2, 'b) Session.Monadic.t
      val ( >>> ) :
        ('t0, 't1, 'a) Session.Monadic.t ->
        ('t1, 't2, 'b) Session.Monadic.t -> ('t0, 't2, 'b) Session.Monadic.t
      val fix :
        (('t0, 't1, 'a) Session.Monadic.t -> ('t0, 't1, 'a) Session.Monadic.t) ->
        ('t0, 't1, 'a) Session.Monadic.t
      val connect :
        (('a, 'b) Session.st, Session.et, unit) Session.Monadic.t ->
        (('b, 'a) Session.st, Session.et, 'm) Session.Monadic.t -> 'm
      val receive :
        (('m * ('a, 'b) Session.st) Session.it, ('a, 'b) Session.st, 'm)
        Session.Monadic.t
      val send :
        '->
        (('m * ('b, 'a) Session.st) Session.ot, ('a, 'b) Session.st, unit)
        Session.Monadic.t
      val branch :
        ('t0, 't2, 'a) Session.Monadic.t ->
        ('t1, 't2, 'a) Session.Monadic.t ->
        (('t0, 't1) Session.choice Session.it, 't2, 'a) Session.Monadic.t
      val select_true :
        ((('b, 'a) Session.st, ('d, 'c) Session.st) Session.choice Session.ot,
         ('a, 'b) Session.st, unit)
        Session.Monadic.t
      val select_false :
        ((('b, 'a) Session.st, ('d, 'c) Session.st) Session.choice Session.ot,
         ('c, 'd) Session.st, unit)
        Session.Monadic.t
    end
end