package yocaml

  1. Overview
  2. Docs

Module Yocaml.EffSource

An overlay on expression and effect performance.

Currently (OCaml 5.2.x), the definition and interpretation of effects is a feature dedicated to implementing concurrent primitives for OCaml, for example: the Domain API. However, the effects type system has not yet been implemented, so the use of effects and handlers is still experimental.

In YOCaml 1.0.0, effects were abstracted using a Freer Monad, described in the Preface. However, since OCaml 5, it has been possible to describe effects, in order to be able to colour the functions which propagate effects, we use an IO Monad. This allows us to distinguish pure functions from impure functions, while allowing the interpretation, a posteriori of effects, allowing specialisation via a Runtime to ensure the versatility of YOCaml. The trade-off is that you can't really take advantage of the direct style, but the presence of binding operators makes this loss fairly slight.

The Eff Monad

The Eff Monad is an implementation of IO, which produces functions that propagate effects. It is used to distinguish between pure and impure functions.

Sourcetype 'a t

A type describing an impure normal form. A function from 'a -> 'b should be pure, and a function of 'a -> 'b Eff.t should be impure and, in retrospect, be interpreted by an effect handler.

Sourceval return : 'a -> 'a t

return x lift x into an impure context.

Sourceval bind : ('a -> 'b t) -> 'a t -> 'b t

bind f x gives the result of the computation x to the function f.

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

map f x mapping from 'a t to 'b t.

Sourceval join : 'a t t -> 'a t

join x remove one level of monadic structure, projecting its bound argument into the outer level.

Sourceval compose : ('a -> 'b t) -> ('b -> 'c t) -> 'a -> 'c t

compose f g is left to right composition of Kleisli Arrows of f . g.

Sourceval rcompose : ('b -> 'c t) -> ('a -> 'b t) -> 'a -> 'c t

rcompose f g is the right to left composition of Kleisli Arrows of g . f.

Sourceval apply : ('a -> 'b) t -> 'a t -> 'b t

apply f x apply f to x.

Sourceval zip : 'a t -> 'b t -> ('a * 'b) t

zip x y is the monoidal product of x and y.

Sourceval replace : 'a -> 'b t -> 'a t

replace x e replace the value of e by x.

Sourceval void : 'a t -> unit t

void e replace the value of e by unit.

Sourceval select : ('a, 'b) Either.t t -> ('a -> 'b) t -> 'b t

select e f apply f if e is Left. It allow to skip effect using Right.

Sourceval branch : ('a, 'b) Either.t t -> ('a -> 'c) t -> ('b -> 'c) t -> 'c t

branch x f g if x is Left, it performs f, otherwise it performs g.

Sourceval map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t

Lift a 2-ary function.

Sourceval map3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t

Lift a 3-ary function.

Sourceval map4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t

Lift a 4-ary function.

Sourceval map5 : ('a -> 'b -> 'c -> 'd -> 'e -> 'f) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t

Lift a 5-ary function.

Sourceval map6 : ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> 'g t

Lift a 6-ary function.

Sourceval map7 : ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> 'h) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> 'g t -> 'h t

Lift a 7-ary function.

Sourceval map8 : ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g -> 'h -> 'i) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> 'g t -> 'h t -> 'i t

Lift a 8-ary function.

Traversable

Enables traversable structures to be traversed on effects.

Sourcemodule List : sig ... end

Infix operators

Comfort infix operators for composing programmes that produce effects.

Sourcemodule Infix : sig ... end
Sourceval (<$>) : ('a -> 'b) -> 'a t -> 'b t

f <$> x is map f x.

Sourceval (<*>) : ('a -> 'b) t -> 'a t -> 'b t

f <*> x is apply f x.

Sourceval (<*?) : ('a, 'b) Either.t t -> ('a -> 'b) t -> 'b t

c <*? f is select c f

Sourceval (>>=) : 'a t -> ('a -> 'b t) -> 'b t

m >>= f is bind f m.

Sourceval (=<<) : ('a -> 'b t) -> 'a t -> 'b t

f =<< m is bind f m.

Sourceval (>|=) : 'a t -> ('a -> 'b) -> 'b t

m >|= f is map f m.

Sourceval (=|<) : ('a -> 'b) -> 'a t -> 'b t

f =|< x is map f x.

Sourceval (>=>) : ('a -> 'b t) -> ('b -> 'c t) -> 'a -> 'c t

f >=> g is compose f g.

Sourceval (<=<) : ('b -> 'c t) -> ('a -> 'b t) -> 'a -> 'c t

f <=< g is rcompose f g.

Bindings operators

Comfort bindings operators for composing programmes that produce effects and get closer to the direct style.

Sourcemodule Syntax : sig ... end
Sourceval (let+) : 'a t -> ('a -> 'b) -> 'b t

let+ x = e in f x is f <$> x

Sourceval (and+) : 'a t -> 'b t -> ('a * 'b) t

let+ x = e and+ y = f in g x y is g <$> e <*> f.

Sourceval (let*) : 'a t -> ('a -> 'b t) -> 'b t

let* x = e in f x is e >>= f.

User defined effects

Description of the effects that can be propagated by a YOCaml program. All effects are prefixed with Yocaml_ to avoid conflicts with another program propagating different effects.

Some effects are common (for example those used to log or propagate errors), some are used to act on the original filesystem and uses a parameter `Source and others act on the target and uses a parameter `Target. This makes it possible, for example, to generate in a target different from the source. This is useful, for example, when generating a site in a git repository, which uses a Unix file system as its source and a git repo as its target.

Sourcetype filesystem = [
  1. | `Source
  2. | `Target
]
Sourcetype Effect.t +=
  1. | Yocaml_log : ([ `App | `Error | `Warning | `Info | `Debug ] * string) -> unit Effect.t
    (*

    Effect describing the logging of a message attached to a log level. The log level uses the various conventional levels offered, in particular, by the Logs library.

    *)
  2. | Yocaml_failwith : exn -> 'a Effect.t
    (*

    Effect that propagates an error.

    *)
  3. | Yocaml_get_time : unit -> int Effect.t
    (*

    Effect that get the current time.

    *)
  4. | Yocaml_file_exists : filesystem * Path.t -> bool Effect.t
    (*

    Effect that check if a file exists.

    *)
  5. | Yocaml_read_file : filesystem * Path.t -> string Effect.t
    (*

    Effect that read a file from a given filepath.

    *)
  6. | Yocaml_get_mtime : filesystem * Path.t -> int Effect.t
    (*

    Effect that get the modification time of a filepath.

    *)
  7. | Yocaml_hash_content : string -> string Effect.t
    (*

    Effect that hashes a string (used to hide the result of a transformation).

    *)
  8. | Yocaml_write_file : filesystem * Path.t * string -> unit Effect.t
    (*

    Effect which describes the writing of a file

    *)
  9. | Yocaml_is_directory : filesystem * Path.t -> bool Effect.t
    (*

    Effect that returns check if a file is a directory or not.

    *)
  10. | Yocaml_read_dir : filesystem * Path.t -> Path.fragment list Effect.t
    (*

    Effect that returns a list of names of files (and directory) present in the given directory. (Names should be not prefixed by the given path).

    *)
  11. | Yocaml_create_dir : filesystem * Path.t -> unit Effect.t
    (*

    Effect that create a directory.

    *)
  12. | Yocaml_exec_command : string * string list * (int -> bool) -> string Effect.t
    (*

    Effect that perform an Unix call.

    *)
Sourceval perform : 'a Effect.t -> 'a t

perform effect colours an effect performance as impure. Replaces Stdlib.Effect.perform x.

Sourceval run : ('b, 'c) Effect.Deep.handler -> ('a -> 'b t) -> 'a -> 'c

run handler kleisli_arrow input interprets a Kleisli Arrow (kleisli_arrow) for an effect handler (effect_handler) given as an argument (input).

Exceptions

Exception that can be propagated by the performance of effects.

Sourceexception File_not_exists of filesystem * Path.t

Exception raised when a file does not exists.

Sourceexception Invalid_path of filesystem * Path.t

Exception raised when a file does not has a basename.

Sourceexception File_is_a_directory of filesystem * Path.t

Exception raised when we try to use a directory as a regular file.

Sourceexception Directory_is_a_file of filesystem * Path.t

Exception raised when we try to use a file as a directory.

Sourceexception Directory_not_exists of filesystem * Path.t

Exception raised when we try to use a directory as a regular file.

Sourceexception Provider_error of Required.provider_error

Exception raised when we try to validate an invalid source of metadata.

Helpers for performing effects

Functions producing defined effects.

Sourceval log : ?level:[ `App | `Error | `Warning | `Info | `Debug ] -> string -> unit t

log ~level message performs the effect Yocaml_log with a given level and a message.

Sourceval logf : ?level:[ `App | `Error | `Warning | `Info | `Debug ] -> ('a, Format.formatter, unit, unit t) format4 -> 'a

logf ~level format performs the effect Yocaml_log with a given level and using a format (like Printf).

Sourceval raise : exn -> 'a t

raise exn performs the effect Yocaml_failwith with a given exn.

Sourceval failwith : string -> 'a t

failwith message perform the effect Yocaml_failwith with a message that produces an error wrapped into a Failure exception.

Sourceval get_time : unit -> int t

get_time () returns the current timestamp.

Sourceval exec : ?is_success:(int -> bool) -> string -> ?args:string list -> string t

exec ?is_success prog ?args will executes prog ...args. When is_success is provided, it is called with the exit code to determine whether it indicates success or failure. Without is_success, success requires the process to return an exit code of 0.

printing on standard output is returned.

Sourceval exec_cmd : ?is_success:(int -> bool) -> Cmd.t -> string t

exec_cmd ?is_success cmd is exec but relaying on Yocaml.Cmd for describing a shell call.

Sourceval file_exists : on:filesystem -> Path.t -> bool t

file_exists ~on path perform the effect Yocaml_file_exists with a given path return true if the file exists, false if not.

Sourceval read_file : on:filesystem -> Path.t -> string t

read_file ~on path perform the effect Yocaml_read_file with a given path and try to read it. Perform Yocaml_failwith with File_not_exists if the file does not exists.

Sourceval read_file_as_metadata : (module Required.DATA_PROVIDER) -> (module Required.DATA_READABLE with type t = 'a) -> on:filesystem -> Path.t -> 'a t

read_file_as_metadata (module P) (module R) ~on path reads a file located by a path on a data source (on) and validates the content as metadata according to a Yocaml.Required.DATA_PROVIDER, P, using the description provided by R of type Yocaml.Required.DATA_READABLE.

Sourceval read_file_with_metadata : (module Required.DATA_PROVIDER) -> (module Required.DATA_READABLE with type t = 'a) -> ?extraction_strategy:Metadata.extraction_strategy -> on:filesystem -> Path.t -> ('a * string) t

read_file_with_metadata (module P) (module R) ?extraction_strategy ~on path reads a file located by a path on a data source (on) and uses an extraction_strategy to separate the metadata from the content and validates the metadata according to a Yocaml.Required.DATA_PROVIDER, P, using the description provided by R of type Yocaml.Required.DATA_READABLE.

Sourceval mtime : on:filesystem -> Path.t -> int t

mtime ~on path perform the effect Yocaml_source_get_mtime with a given path and try to get the modification time. Perform Yocaml_failwith with File_not_exists if the file does not exists.

The logic of mtime differs slightly from that of Unix. If a directory is given as an argument, the function will return the largest mtime recursively contained in the directory. This makes it easy to treat directories as dependency sets.

Sourceval hash : string -> string t

hash str perform the effect Yocaml_hash_content on a given string.

Sourceval create_directory : on:filesystem -> Path.t -> unit t

create_directory ~on target performs recursively Yocaml_create_dir to create a directory.

Sourceval write_file : on:filesystem -> Path.t -> string -> unit t

write_file ~on target content performs the effect Yocaml_write_file that should writes a file to a given target. The function use Yocaml.Eff.create_directory for creating intermediate directory in the path.

Sourceval is_directory : on:filesystem -> Path.t -> bool t

is_directory ~on target performs the effect Yocaml_is_directory that should check if a file is a directory or not.

Sourceval is_file : on:filesystem -> Path.t -> bool t

is_file ~on target performs the effect Yocaml_is_directory and if the file is not a directory, it return true, false otherwise.

Sourceval read_directory : on:filesystem -> ?only:[ `Files | `Directories | `Both ] -> ?where:(Path.t -> bool) -> Path.t -> Path.t list t

read_directory ~on ?only ?where path returns a list of children (as a pair of the full path and the name (fragment) of the child) of the given directory, performing Yocaml_read_dir.

Sourceval copy_recursive : ?new_name:Path.fragment -> into:Path.t -> Path.t -> unit t

copy_recursive ~on path copy (recursively) a directory or a file into another one.

Sourceval get_basename : Path.t -> Path.fragment t

get_basename path returns the basename of a path (and fail if the path has no basename).

OCaml

Innovation. Community. Security.