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