sig
  module Make :
    sig
      type 'a io = 'Lwt.t
      type chan_endpoint = Lwt_io.input_channel * Lwt_io.output_channel
      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