sig
  module Simple :
    sig
      type ('a, 'b) enum = {
        start : unit -> 'a;
        step : '-> ('b * 'a) option;
      }
      val enum_of_interval : int -> int -> (int, int) JoinPool.Simple.enum
      val enum_of_list : 'a list -> ('a list, 'a) JoinPool.Simple.enum
      type ('a, 'b, 'c) t = {
        register : ('-> 'b) Join.chan;
        wait : unit -> 'c;
      }
      val create :
        ('a, 'b) JoinPool.Simple.enum ->
        ('-> '-> 'd) -> '-> ('b, 'c, 'd) JoinPool.Simple.t
    end
  module Shared :
    sig
      module type Config = sig val debug : bool val nagain : int end
      module type Enumerable =
        sig
          type t
          type elt
          type enum
          val start :
            JoinPool.Shared.Enumerable.t -> JoinPool.Shared.Enumerable.enum
          val step :
            JoinPool.Shared.Enumerable.enum ->
            (JoinPool.Shared.Enumerable.elt * JoinPool.Shared.Enumerable.enum)
            option
        end
      type ('a, 'b) worker = '-> 'b
      type subtask_id = int
      type ('a, 'b) interruptible_worker =
          JoinPool.Shared.subtask_id * '-> 'b option
      type kill = JoinPool.Shared.subtask_id Join.chan
      module type S =
        sig
          type elt
          type collection
          type ('a, 'b) t = {
            register :
              (JoinPool.Shared.S.elt, 'a) JoinPool.Shared.worker Join.chan;
            register_interruptible :
              ((JoinPool.Shared.S.elt, 'a)
               JoinPool.Shared.interruptible_worker * JoinPool.Shared.kill)
              Join.chan;
            fold :
              JoinPool.Shared.S.collection -> ('-> '-> 'b) -> '-> 'b;
          }
          val create : unit -> ('a, 'b) JoinPool.Shared.S.t
        end
      module Make :
        functor (C : Config->
          functor (E : Enumerable->
            sig
              type elt = E.elt
              type collection = E.t
              type ('a, 'b) t = {
                register : (elt, 'a) worker Join.chan;
                register_interruptible :
                  ((elt, 'a) interruptible_worker * kill) Join.chan;
                fold : collection -> ('-> '-> 'b) -> '-> 'b;
              }
              val create : unit -> ('a, 'b) t
            end
    end
end