sig
  type 'a scheduler
  val create : ?compare:('-> '-> int) -> unit -> 'Duppy.scheduler
  val queue :
    ?log:(string -> unit) ->
    ?priorities:('-> bool) -> 'Duppy.scheduler -> string -> unit
  val stop : 'Duppy.scheduler -> unit
  module Task :
    sig
      type ('a, 'b) task = {
        priority : 'a;
        events : 'b list;
        handler : 'b list -> ('a, 'b) Duppy.Task.task list;
      }
      type event =
          [ `Delay of float
          | `Exception of Unix.file_descr
          | `Read of Unix.file_descr
          | `Write of Unix.file_descr ]
      val add :
        'Duppy.scheduler ->
        ('a, [< Duppy.Task.event ]) Duppy.Task.task -> unit
    end
  module Async :
    sig
      type t
      exception Stopped
      val add :
        priority:'-> 'Duppy.scheduler -> (unit -> float) -> Duppy.Async.t
      val wake_up : Duppy.Async.t -> unit
      val stop : Duppy.Async.t -> unit
    end
  module Io :
    sig
      type marker = Length of int | Split of string
      type bigarray =
          (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
          Bigarray.Array1.t
      type failure =
          Io_error
        | Unix of Unix.error * string * string
        | Unknown of exn
        | Timeout
      val read :
        ?recursive:bool ->
        ?init:string ->
        ?on_error:(string * Duppy.Io.failure -> unit) ->
        ?timeout:float ->
        priority:'->
        'Duppy.scheduler ->
        Unix.file_descr ->
        Duppy.Io.marker -> (string * string option -> unit) -> unit
      val write :
        ?exec:(unit -> unit) ->
        ?on_error:(Duppy.Io.failure -> unit) ->
        ?bigarray:Duppy.Io.bigarray ->
        ?string:string ->
        ?timeout:float ->
        priority:'-> 'Duppy.scheduler -> Unix.file_descr -> unit
    end
  module Monad :
    sig
      type ('a, 'b) t
      val return : '-> ('a, 'b) Duppy.Monad.t
      val raise : '-> ('a, 'b) Duppy.Monad.t
      val bind :
        ('a, 'b) Duppy.Monad.t ->
        ('-> ('c, 'b) Duppy.Monad.t) -> ('c, 'b) Duppy.Monad.t
      val ( >>= ) :
        ('a, 'b) Duppy.Monad.t ->
        ('-> ('c, 'b) Duppy.Monad.t) -> ('c, 'b) Duppy.Monad.t
      val run :
        return:('-> unit) ->
        raise:('-> unit) -> ('a, 'b) Duppy.Monad.t -> unit
      val catch :
        ('a, 'b) Duppy.Monad.t ->
        ('-> ('a, 'c) Duppy.Monad.t) -> ('a, 'c) Duppy.Monad.t
      val ( =<< ) :
        ('-> ('a, 'c) Duppy.Monad.t) ->
        ('a, 'b) Duppy.Monad.t -> ('a, 'c) Duppy.Monad.t
      val fold_left :
        ('-> '-> ('a, 'c) Duppy.Monad.t) ->
        '-> 'b list -> ('a, 'c) Duppy.Monad.t
      val iter :
        ('-> (unit, 'b) Duppy.Monad.t) ->
        'a list -> (unit, 'b) Duppy.Monad.t
      module Mutex :
        sig
          module type Mutex_control =
            sig
              type priority
              val scheduler :
                Duppy.Monad.Mutex.Mutex_control.priority Duppy.scheduler
              val priority : Duppy.Monad.Mutex.Mutex_control.priority
            end
          module type Mutex_t =
            sig
              type mutex
              module Control : Mutex_control
              val create : unit -> Duppy.Monad.Mutex.Mutex_t.mutex
              val lock :
                Duppy.Monad.Mutex.Mutex_t.mutex -> (unit, 'a) Duppy.Monad.t
              val try_lock :
                Duppy.Monad.Mutex.Mutex_t.mutex -> (bool, 'a) Duppy.Monad.t
              val unlock :
                Duppy.Monad.Mutex.Mutex_t.mutex -> (unit, 'a) Duppy.Monad.t
            end
          module Factory : functor (Control : Mutex_control-> Mutex_t
        end
      module Condition :
        sig
          module Factory :
            functor (Mutex : Mutex.Mutex_t->
              sig
                type condition
                val create : unit -> Duppy.Monad.Condition.Factory.condition
                val wait :
                  Duppy.Monad.Condition.Factory.condition ->
                  Mutex.mutex -> (unit, 'a) Duppy.Monad.t
                val broadcast :
                  Duppy.Monad.Condition.Factory.condition ->
                  (unit, 'a) Duppy.Monad.t
                val signal :
                  Duppy.Monad.Condition.Factory.condition ->
                  (unit, 'a) Duppy.Monad.t
              end
        end
      module Io :
        sig
          type ('a, 'b) handler = {
            scheduler : 'Duppy.scheduler;
            socket : Unix.file_descr;
            mutable data : string;
            on_error : Duppy.Io.failure -> 'b;
          }
          val exec :
            ?delay:float ->
            priority:'->
            ('a, 'b) Duppy.Monad.Io.handler ->
            ('c, 'b) Duppy.Monad.t -> ('c, 'b) Duppy.Monad.t
          val delay :
            priority:'->
            ('a, 'b) Duppy.Monad.Io.handler ->
            float -> (unit, 'b) Duppy.Monad.t
          val read :
            ?timeout:float ->
            priority:'->
            marker:Duppy.Io.marker ->
            ('a, 'b) Duppy.Monad.Io.handler -> (string, 'b) Duppy.Monad.t
          val read_all :
            ?timeout:float ->
            priority:'->
            'Duppy.scheduler ->
            Unix.file_descr ->
            (string, string * Duppy.Io.failure) Duppy.Monad.t
          val write :
            ?timeout:float ->
            priority:'->
            ('a, 'b) Duppy.Monad.Io.handler ->
            string -> (unit, 'b) Duppy.Monad.t
          val write_bigarray :
            ?timeout:float ->
            priority:'->
            ('a, 'b) Duppy.Monad.Io.handler ->
            Duppy.Io.bigarray -> (unit, 'b) Duppy.Monad.t
        end
    end
end