Module Yocaml.Eff
Source
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 : ([ `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.
| Yocaml_failwith : exn -> 'a Effect.t
Effect that propagates an error.
| Yocaml_get_time : unit -> int Effect.t
Effect that get the current time.
| Yocaml_file_exists : filesystem * Path.t -> bool Effect.t
Effect that check if a file exists.
| Yocaml_read_file : filesystem * Path.t -> string Effect.t
Effect that read a file from a given filepath.
| Yocaml_get_mtime : filesystem * Path.t -> int Effect.t
Effect that get the modification time of a filepath.
| Yocaml_hash_content : string -> string Effect.t
Effect that hashes a string (used to hide the result of a transformation).
| Yocaml_write_file : filesystem * Path.t * string -> unit Effect.t
Effect which describes the writing of a file
| Yocaml_is_directory : filesystem * Path.t -> bool Effect.t
Effect that returns check if a file is a directory or not.
| 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).
| Yocaml_create_dir : filesystem * Path.t -> unit Effect.t
Effect that create a directory.
| Yocaml_exec_command : string * string list * (int -> bool) -> string Effect.t
Effect 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 :
?level:[ `App | `Error | `Warning | `Info | `Debug ] ->
string ->
unit t
log ~level message
performs the effect Yocaml_log
with a given level
and a message
.
logf ~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 ~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.
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).