type 'a res = [ | `Ok of '| `Error of exn ]

module type IO_Type =
  sig
    type +'a m
    
    val return : '-> 'a m
      
    val bind : ('-> 'b m) -> 'a m -> 'b m
      
    val bind_rev : 'a m -> ('-> 'b m) -> 'b m
      
    val error : exn -> 'a m
      
    val catch : (unit -> 'a m) -> (exn -> 'a m) -> 'a m
      
    type output_channel
    
    val stdout : output_channel
      
    val write : output_channel -> string -> unit m
      
    val write_from : output_channel -> string -> int -> int -> int m
      
    type input_channel
    
    val open_in : string -> input_channel m
      
    val close_in : input_channel -> unit m
      
    (* Lwt_io.close inch *)
    val read_into : input_channel -> string -> int -> int -> int m
      
    (* in lwt: read_into ic buffer offset length *)
    val runIO : 'a m -> 'a res
      
    val flush : output_channel -> unit m
      
    val printf : ('a, unit, string, unit m) format4 -> 'a
      
    val close_out : output_channel -> unit m
      
    val run_and_ignore_result : unit m -> unit
      
    type server
    
    val establish_server :
      ?buffer_size: int ->
        ?backlog: int ->
          Unix.sockaddr ->
            ((input_channel * output_channel) -> unit) -> server
      
    val shutdown_server : server -> unit
      
    val wait_server : server -> unit m
      
  end
  
(*
value stdin = Lwt_io.stdin;

value printf fmt = Printf.ksprintf (write stdout) fmt;

value flush = Lwt_io.flush;

value close_out = Lwt_io.close;

*)

(*
module Test = (IO_Lwt : IO_Type)
;
*)

module type FUNCTOR = sig type 'a t
                           val fmap : ('-> 'b) -> 'a t -> 'b t
                              end
  
module type MONAD_SEQUENCE =
  sig
    type 'a m
    
    val return : '-> 'a m
      
    val bind_rev : 'a m -> ('-> 'b m) -> 'b m
      
    val sequence_array : ('a m) array -> ('a array) m
      
  end