Ui_effectmodule type Handler = sig ... endmodule type S = sig ... end'a Effect.t represents some computation of type 'a that can be performed outside of the typical computational/incremental structure of a Bonsai program . Examples of this computation might be:
If you have a value of type 'a Effect.t, you can schedule it to be run by calling inject and providing a function that will be called when the callback completes.
include Base.Monad.S with type 'a t := 'a tval return : 'a 'i 'p 'q. 'a -> 'a tConvert a value to a t.
Sequences computations. bind t ~f computes f v for value(s) v in t. Well-behaved monads satisfy these "laws" (where ( >>= ) is the infix bind operator):
map t ~f is equivalent to bind t ~f:(fun x -> return (f x))return x >>= f is equivalent to f xt >>= return is equivalent to t(t >>= f) >>= g is equivalent to t >>= fun x -> f x >>= gCombines nested t into just one layer. Equivalent to bind t ~f:Fn.id.
Ignores contained values of t. Equivalent to map t ~f:ignore.
module Monad_infix : sig ... endmodule Let_syntax : sig ... endmodule Par : Base.Monad.S with type 'a t := 'a tThe Par module contains a Let_syntax whose both function executes the effects in parallel.
val never : 'a tAn effect that never completes
Produces an effect that raises an exception when the effect is performed.
Note: As long as this is handled by either try_with/try_with_or_error or Expert.handle/Expert.eval (with a non-raising on_exn), no exceptions will ever actually be raised. This should be safe to use in environments where raising exceptions is costly (or at the very least, better than raising directly).
val raise_s : Base.Sexp.t -> 'a tval raise_error : Base.Error.t -> 'a tval lower_result : ('a, Base.Exn.t) Base.Result.t t -> 'a tLike Result.ok_exn, except with the performance-friendly properties of raise.
val lower_or_error : 'a Base.Or_error.t t -> 'a tLike Or_error.ok_exn, except with the performance-friendly properties of raise_error.
val try_with :
?rest:[ `Raise | `Call of Base.Exn.t -> Base.unit ] ->
'a t ->
('a, Base.Exn.t) Base.Result.t tIf evaluating the given effect produces an exception before producing a value, try_with will return the first exn in the error side of the Result.t.
If rest is `Call f, try_with will use f to handle any further exns produced. Otherwise, they will be raised further (i.e. visible to iter_errors, try_with, and eventual Expert.handle/Expert.eval calls), although they cannot cause the effect itself to raise (i.e. further try_withs will result in Ok and handle them via its rest parameter).
val try_with_or_error :
?rest:[ `Raise | `Call of Base.Exn.t -> Base.unit ] ->
'a t ->
'a Base.Or_error.t tLike try_with, but returns the exn as an Error.t.
val iter_errors : 'a t -> f:(Base.Exn.t -> Base.unit t) -> 'a tIf exceptions are produced in the course of evaluating the input effect, the function passed to iter_errors will be invoked with those errors. Multiple errors can be produced from functions such as both_parallel, all_parallel, and protect. This doesn't _handle_ the errors, but you can record or print the error. Throwing an exception inside of f will not recursively invoke f on the new error that is produced.
Note that iter_errors only calls f on exns as they are produced; it does not wait for more exns before letting an exn continue to raise. For example, iter_errors (both_parallel (raise a) (raise b)) ~f will evaluate f a, raise a to its next handler, evaluate f b, and then raise b to its next handler.
protect runs an effect, and after the effect completes (including if it fails with an exception), it also runs the finally effect.
If the given effect raises an exception, protect will output an effect that also raises that exception after executing finally (even if finally also raises). If finally raises (but not the given effect), the output of protect will raise with that exception.
evaluates both effects in parallel and returns their product when both complete
evaluates all effects in the list in parallel and returns the list of results when all of them complete. The output list is always the same length as the input list.
like all_parallel, but for unit Effect.ts.
val lazy_ : 'a t Base.Lazy.t -> 'a tIf creating an effect could be expensive, you can wrap its construction in a lazy and pass it to this function so that its construction will be deferred until it's about to be evaluated.
val print_s : Base.Sexp.t -> Base.unit tPrints the sexp when scheduled.
val of_sync_fun : ('query -> 'result) -> 'query -> 'result tof_sync_fun is similar to of_deferred_fun but with a synchronous function instead of a deferred one. This can be used for functions that are synchronous but side-effecting, or as a mock-function in tests that replace the usages of of_deferred_fun in the actual app.
Note that, unlike of_deferred_fun, the function must return immediately, so it's not possible to test the behaviour of tour app between calling the function and the effect becoming 'determined'. If you need to do this, see of_svar and of_query_response_tracker below.
Like of_sync_fun but with a pre-applied unit query. Side-effects in the function will be run every time that the resulting effect is scheduled
val of_sync_fun' :
('query -> on_exn:(Base.Exn.t -> Base.unit) -> 'result) ->
'query ->
'result tLike of_sync_fun but with an extra on_exn parameter that can be passed into calls to Expert.handle.
val of_thunk' :
(Base.unit -> on_exn:(Base.Exn.t -> Base.unit) -> 'result) ->
'result tLike of_thunk but with an extra on_exn parameter that can be passed into calls to Expert.handle.
module Expert : sig ... endmodule Private : sig ... endmodule Result : sig ... endResult is extremely similar to Deferred.Result
module Or_error : sig ... endLike Result above, this is extremely similar to Deferred.Or_error. A lot of the additional functions are missing, but can be added as needed
module For_testing : sig ... end