sig
  module type IO =
    sig
      type 'a t
      type chan_endpoint
      type chan =
          Chan : Binary_session.IO.chan_endpoint *
            Binary_session.IO.chan_endpoint -> Binary_session.IO.chan
      val make_channel : unit -> Binary_session.IO.chan
      val read_channel :
        Binary_session.IO.chan_endpoint -> 'Binary_session.IO.t
      val write_channel :
        '->
        flags:Marshal.extern_flags list ->
        Binary_session.IO.chan_endpoint -> unit Binary_session.IO.t
      val close_channel : Binary_session.IO.chan -> unit Binary_session.IO.t
      val return : '-> 'Binary_session.IO.t
      val ( >>= ) :
        'Binary_session.IO.t ->
        ('-> 'Binary_session.IO.t) -> 'Binary_session.IO.t
    end
  module type Binary_process =
    sig
      type 'a io
      type chan_endpoint
      type ('a, 'b) session constraint 'a = [>  ] constraint 'b = [>  ]
      type ('a, 'b, 'c) process
      val send :
        '->
        (unit,
         ([ `Send of 'a * ([>  ] as 'b) ], [ `Recv of 'a * ([>  ] as 'c) ])
         Binary_session.Binary_process.session,
         ('b, 'c) Binary_session.Binary_process.session)
        Binary_session.Binary_process.process
      val recv :
        unit ->
        ('a,
         ([ `Recv of 'a * ([>  ] as 'b) ], [ `Send of 'a * ([>  ] as 'c) ])
         Binary_session.Binary_process.session,
         ('b, 'c) Binary_session.Binary_process.session)
        Binary_session.Binary_process.process
      val offer :
        ('e,
         ([>  ] as 'a, [>  ] as 'b) Binary_session.Binary_process.session,
         'f)
        Binary_session.Binary_process.process ->
        ('e,
         ([>  ] as 'c, [>  ] as 'd) Binary_session.Binary_process.session,
         'f)
        Binary_session.Binary_process.process ->
        ('e,
         ([ `Offer of
              ('a, 'b) Binary_session.Binary_process.session *
              ('c, 'd) Binary_session.Binary_process.session ],
          [ `Choice of
              ('b, 'a) Binary_session.Binary_process.session *
              ('d, 'c) Binary_session.Binary_process.session ])
         Binary_session.Binary_process.session, 'f)
        Binary_session.Binary_process.process
      val choose_left :
        ('e,
         ([>  ] as 'a, [>  ] as 'b) Binary_session.Binary_process.session,
         'f)
        Binary_session.Binary_process.process ->
        ('e,
         ([ `Choice of
              ('a, 'b) Binary_session.Binary_process.session *
              ([>  ] as 'c, [>  ] as 'd)
              Binary_session.Binary_process.session ],
          [ `Offer of
              ('b, 'a) Binary_session.Binary_process.session *
              ('d, 'c) Binary_session.Binary_process.session ])
         Binary_session.Binary_process.session, 'f)
        Binary_session.Binary_process.process
      val choose_right :
        ('e,
         ([>  ] as 'a, [>  ] as 'b) Binary_session.Binary_process.session,
         'f)
        Binary_session.Binary_process.process ->
        ('e,
         ([ `Choice of
              ([>  ] as 'c, [>  ] as 'd)
              Binary_session.Binary_process.session *
              ('a, 'b) Binary_session.Binary_process.session ],
          [ `Offer of
              ('d, 'c) Binary_session.Binary_process.session *
              ('b, 'a) Binary_session.Binary_process.session ])
         Binary_session.Binary_process.session, 'f)
        Binary_session.Binary_process.process
      val stop :
        '->
        ('a, ([ `Stop ], [ `Stop ]) Binary_session.Binary_process.session,
         unit)
        Binary_session.Binary_process.process
      val lift_io :
        'Binary_session.Binary_process.io ->
        ('a, 'b, 'b) Binary_session.Binary_process.process
      val return : '-> ('a, 'b, 'b) Binary_session.Binary_process.process
      val ( >>= ) :
        ('a, 'b, 'c) Binary_session.Binary_process.process ->
        ('-> ('d, 'c, 'e) Binary_session.Binary_process.process) ->
        ('d, 'b, 'e) Binary_session.Binary_process.process
      val run_processes :
        ('a,
         ([>  ] as 'b, [>  ] as 'c) Binary_session.Binary_process.session,
         unit)
        Binary_session.Binary_process.process ->
        ('d, ('c, 'b) Binary_session.Binary_process.session, unit)
        Binary_session.Binary_process.process ->
        ((unit -> 'Binary_session.Binary_process.io) *
         (unit -> 'Binary_session.Binary_process.io))
        Binary_session.Binary_process.io
    end
  module Make :
    functor (I : IO->
      sig
        type 'a io = 'I.t
        type chan_endpoint = I.chan_endpoint
        type ('a, 'b) session constraint 'a = [>  ] constraint 'b = [>  ]
        type ('a, 'b, 'c) process
        val send :
          '->
          (unit,
           ([ `Send of 'a * ([>  ] as 'b) ], [ `Recv of 'a * ([>  ] as 'c) ])
           session, ('b, 'c) session)
          process
        val recv :
          unit ->
          ('a,
           ([ `Recv of 'a * ([>  ] as 'b) ], [ `Send of 'a * ([>  ] as 'c) ])
           session, ('b, 'c) session)
          process
        val offer :
          ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
          ('e, ([>  ] as 'c, [>  ] as 'd) session, 'f) process ->
          ('e,
           ([ `Offer of ('a, 'b) session * ('c, 'd) session ],
            [ `Choice of ('b, 'a) session * ('d, 'c) session ])
           session, 'f)
          process
        val choose_left :
          ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
          ('e,
           ([ `Choice of
                ('a, 'b) session * ([>  ] as 'c, [>  ] as 'd) session ],
            [ `Offer of ('b, 'a) session * ('d, 'c) session ])
           session, 'f)
          process
        val choose_right :
          ('e, ([>  ] as 'a, [>  ] as 'b) session, 'f) process ->
          ('e,
           ([ `Choice of
                ([>  ] as 'c, [>  ] as 'd) session * ('a, 'b) session ],
            [ `Offer of ('d, 'c) session * ('b, 'a) session ])
           session, 'f)
          process
        val stop : '-> ('a, ([ `Stop ], [ `Stop ]) session, unit) process
        val lift_io : 'a io -> ('a, 'b, 'b) process
        val return : '-> ('a, 'b, 'b) process
        val ( >>= ) :
          ('a, 'b, 'c) process ->
          ('-> ('d, 'c, 'e) process) -> ('d, 'b, 'e) process
        val run_processes :
          ('a, ([>  ] as 'b, [>  ] as 'c) session, unit) process ->
          ('d, ('c, 'b) session, unit) process ->
          ((unit -> 'a io) * (unit -> 'd io)) io
      end
end