package containers

  1. Overview
  2. Docs

IO Monad

A simple abstraction over blocking IO, with strict evaluation. This is in no way an alternative to Lwt/Async if you need concurrency.

  • since 0.3.3

Examples:

  • obtain the list of lines of a file:
let l = CCIO.((with_in "/tmp/some_file" >>>= read_lines) |> run_exn);;
  • transfer one file into another:
# let a = CCIO.(
  with_in "input" >>>= fun ic ->
  with_out ~flags:[Open_creat] "output" >>>= fun oc ->
  Seq.chunks 512 ic
  |> Seq.output oc
) ;;

# run a;;
type 'a t
type 'a io = 'a t
type 'a with_finalizer

A value of type 'a with_finalizer is similar to a value 'a t but also contains a finalizer that must be run to cleanup. See (>>>=) to get rid of it.

type 'a or_error = [
  1. | `Ok of 'a
  2. | `Error of string
]
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t

wait for the result of an action, then use a function to build a new action and execute it

val return : 'a -> 'a t

Just return a value

val repeat : int -> 'a t -> 'a list t

Repeat an IO action as many times as required

val repeat' : int -> 'a t -> unit t

Same as repeat, but ignores the result

val map : ('a -> 'b) -> 'a t -> 'b t

Map values

val (>|=) : 'a t -> ('a -> 'b) -> 'b t
val bind : ?finalize:unit t -> ('a -> 'b t) -> 'a t -> 'b t

bind f a runs the action a and applies f to its result to obtain a new action. It then behaves exactly like this new action.

  • parameter finalize

    an optional action that is always run after evaluating the whole action

val pure : 'a -> 'a t
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
val lift : ('a -> 'b) -> 'a t -> 'b t

Synonym to map

val lift2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
val lift3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t
val sequence : 'a t list -> 'a list t

Runs operations one by one and gather their results

val sequence_map : ('a -> 'b t) -> 'a list -> 'b list t

Generalization of sequence

val fail : string -> 'a t

fail msg fails with the given message. Running the IO value will return an `Error variant

Finalizers

val (>>>=) : 'a with_finalizer -> ('a -> 'b t) -> 'b t

Alternative to (>>=) that also takes a unit t value, that is a finalizer. This action will run in any case (even failure). Other than the finalizer, this behaves like (>>=)

Running

val run : 'a t -> 'a or_error

Run an IO action.

  • returns

    either `Ok x when x is the successful result of the computation, or some `Error "message"

exception IO_error of string
val run_exn : 'a t -> 'a

Unsafe version of run. It assumes non-failure.

  • raises IO_error

    if the execution didn't go well

val register_printer : (exn -> string option) -> unit

register_printer p register p as a possible failure printer. If run a raises an exception e, p e is evaluated. If p e = Some msg then the error message will be msg, otherwise other printers will be tried

Standard Wrappers

Input
val with_in : ?mode:int -> ?flags:Pervasives.open_flag list -> string -> Pervasives.in_channel with_finalizer

Open an input file with the given optional flag list. It yields a in_channel with a finalizer attached. See (>>>=) to use it.

val read : Pervasives.in_channel -> string -> int -> int -> int t

Read a chunk into the given string

val read_line : Pervasives.in_channel -> string option t

Read a line from the channel. Returns None if the input is terminated.

val read_lines : Pervasives.in_channel -> string list t

Read all lines eagerly

val read_all : Pervasives.in_channel -> string t

Read the whole channel into a buffer, then converted into a string

Output
val with_out : ?mode:int -> ?flags:Pervasives.open_flag list -> string -> Pervasives.out_channel with_finalizer

Same as with_in but for an output channel

val with_out_a : ?mode:int -> ?flags:Pervasives.open_flag list -> string -> Pervasives.out_channel with_finalizer

Similar to with_out but with the Open_append and Open_creat flags activated

val write : Pervasives.out_channel -> string -> int -> int -> unit t
val write_str : Pervasives.out_channel -> string -> unit t
val write_buf : Pervasives.out_channel -> Buffer.t -> unit t
val write_line : Pervasives.out_channel -> string -> unit t
val flush : Pervasives.out_channel -> unit t

Streams

Iterators on chunks of bytes, or lines, or any other value using combinators. Those iterators are usable only once, because their source might be usable only once (think of a socket)

module Seq : sig ... end
File and file names

How to list recursively files in a directory:

CCIO.(
  File.read_dir ~recurse:true (File.make "/tmp")
  >>= Seq.output ~sep:"\n" stdout
) |> CCIO.run_exn ;;

See File.walk if you also need to list directories.

module File : sig ... end
module Raw : sig ... end
OCaml

Innovation. Community. Security.