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 :
        ('d, 'a) JoinPool.Simple.enum ->
        ('-> '-> 'c) -> '-> ('a, 'b, 'c) 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 ('elt, 'partial) worker = 'elt -> 'partial
      type subtask_id = int
      type ('elt, 'partial) interruptible_worker =
          JoinPool.Shared.subtask_id * 'elt -> 'partial option
      type kill = JoinPool.Shared.subtask_id Join.chan
      module type S =
        sig
          type elt
          type collection
          type ('partial, 'result) t = {
            register :
              (JoinPool.Shared.S.elt, 'partial) JoinPool.Shared.worker
              Join.chan;
            register_interruptible :
              ((JoinPool.Shared.S.elt, 'partial)
               JoinPool.Shared.interruptible_worker * JoinPool.Shared.kill)
              Join.chan;
            fold :
              JoinPool.Shared.S.collection ->
              ('partial -> 'result -> 'result) -> 'result -> 'result;
          }
          val create : unit -> ('partial, 'result) JoinPool.Shared.S.t
        end
      module Make :
        functor (C : Config->
          functor (E : Enumerable->
            sig
              type elt = E.elt
              type collection = E.t
              type ('partial, 'result) t = {
                register : (elt, 'partial) worker Join.chan;
                register_interruptible :
                  ((elt, 'partial) interruptible_worker * kill) Join.chan;
                fold :
                  collection ->
                  ('partial -> 'result -> 'result) -> 'result -> 'result;
              }
              val create : unit -> ('partial, 'result) t
            end
    end
end