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.
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.
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.
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 zip x y is the monoidal product of x and y.
replace x e replace the value of e by x.
void e replace the value of e by unit.
select e f apply f if e is Left. It allow to skip effect using Right.
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 Sourceval map3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t Sourceval map4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a t -> 'b t -> 'c t -> 'd t -> 'e t Sourceval map5 :
('a -> 'b -> 'c -> 'd -> 'e -> 'f) ->
'a t ->
'b t ->
'c t ->
'd t ->
'e t ->
'f t Sourceval map6 :
('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) ->
'a t ->
'b t ->
'c t ->
'd t ->
'e t ->
'f t ->
'g t 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 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 Traversable
Enables traversable structures to be traversed on effects.
Infix operators
Comfort infix operators for composing programmes that produce effects.
Sourceval (<$>) : ('a -> 'b) -> 'a t -> 'b t Sourceval (<*>) : ('a -> 'b) t -> 'a t -> 'b t Sourceval (>>=) : 'a t -> ('a -> 'b t) -> 'b t Sourceval (=<<) : ('a -> 'b t) -> 'a t -> 'b t Sourceval (>|=) : 'a t -> ('a -> 'b) -> 'b t Sourceval (=|<) : ('a -> 'b) -> 'a t -> 'b t Sourceval (>=>) : ('a -> 'b t) -> ('b -> 'c t) -> 'a -> 'c t Sourceval (<=<) : ('b -> 'c t) -> ('a -> 'b t) -> 'a -> 'c t Bindings operators
Comfort bindings operators for composing programmes that produce effects and get closer to the direct style.
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 = [ | `Source| `Target
] Sourcetype Effect.t += | Yocaml_log : (Logs.src option
* [ `App | `Error | `Warning | `Info | `Debug ]
* string) -> unit Effect.tEffect 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.
| Yocaml_failwith : exn -> 'a Effect.tEffect that propagates an error.
| Yocaml_get_time : unit -> int Effect.tEffect that get the current time.
| Yocaml_file_exists : filesystem * Path.t -> bool Effect.tEffect that check if a file exists.
| Yocaml_read_file : filesystem * bool * Path.t -> string Effect.tEffect that read a file from a given filepath (the second argument is used to notice if we need to perform a snapshot or not of the given file).
| Yocaml_get_mtime : filesystem * Path.t -> int Effect.tEffect that get the modification time of a filepath.
| Yocaml_hash_content : string -> string Effect.tEffect that hashes a string (used to hide the result of a transformation).
| Yocaml_write_file : filesystem * Path.t * string -> unit Effect.tEffect which describes the writing of a file
| Yocaml_is_directory : filesystem * Path.t -> bool Effect.tEffect that returns check if a path is a directory or not.
| Yocaml_is_file : filesystem * Path.t -> bool Effect.tEffect that returns check if a path is a file.
| Yocaml_read_dir : filesystem * Path.t -> Path.fragment list Effect.tEffect that returns a list of names of files (and directory) present in the given directory. (Names should be not prefixed by the given path).
| Yocaml_create_dir : filesystem * Path.t -> unit Effect.tEffect that create a directory.
| Yocaml_exec_command : string * string list * (int -> bool) -> string Effect.tEffect that perform an Unix call.
perform effect colours an effect performance as impure. Replaces Stdlib.Effect.perform x.
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.
Exception raised when a file does not exists.
Exception raised when a file does not has a basename.
Exception raised when we try to use a directory as a regular file.
Exception raised when we try to use a file as a directory.
Exception raised when we try to use a directory as a regular file.
Exception raised when we try to validate an invalid source of metadata.
Functions producing defined effects.
Sourceval log :
?src:Logs.src ->
?level:[ `App | `Error | `Warning | `Info | `Debug ] ->
string ->
unit t log ?src ~level message performs the effect Yocaml_log with a given level and a message.
logf ?src ~level format performs the effect Yocaml_log with a given level and using a format (like Printf).
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.
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.
file_exists ~on path perform the effect Yocaml_file_exists with a given path return true if the file exists, false if not.
read_file ?snapshot ~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. snapshot is used to perform a snapshot of the file.
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.
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.
create_directory ~on target performs recursively Yocaml_create_dir to create a directory.
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.
is_directory ~on target performs the effect Yocaml_is_directory that should check if a file is a directory or not.
is_file ~on target performs the effect Yocaml_is_directory and if the file is not a directory, it return true, false otherwise.
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.
copy_recursive ~on path copy (recursively) a directory or a file into another one.
get_basename path returns the basename of a path (and fail if the path has no basename).