Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Mutex.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sig

val exclusively : (unit -> 'a) -> 'a
val run : (unit -> 'a) -> 'a

val register_printer : ([`Exclusively] -> string option) -> unit
end

module Make () =
Expand All @@ -22,10 +24,16 @@ struct
raise Locked
else begin
S.set true;
(* Favonia: I learn from the developers of eio that Fun.protect is not good at
preserving the backtraces. See https://github.com/ocaml-multicore/eio/pull/209. *)
match f () with
| ans -> S.set false; ans
| exception e -> S.set false; raise e
end

let run f = S.run ~init:false f

let register_printer f = S.register_printer @@ fun _ -> f `Exclusively

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Mutex.run"
end
8 changes: 8 additions & 0 deletions src/Mutex.mli
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ sig
(** [run f] executes the thunk [f] which may perform mutex effects.
Each call of [run] creates a fresh mutex; in particular, calling [run] inside
the thunk [f] will start a new scope that does not interfere with the outer scope. *)

val register_printer : ([`Exclusively] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:Modifier.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.

The input type of the printer [p] is a variant representing internal effects used in this module. It corresponds to all the effects trigger by {!val:exclusively}.

@since 1.1.0
*)
end

module Make () : S
Expand Down
2 changes: 2 additions & 0 deletions src/Reader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ struct
let register_printer f = Printexc.register_printer @@ function
| Effect.Unhandled Read -> f `Read
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Reader.run"
end
2 changes: 1 addition & 1 deletion src/Reader.mli
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ sig

The input type of the printer [p] is a variant representation of the only internal effect used in this module. It corresponds to the effect trigger by {!val:read}.

@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/Sequencer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ struct
let register_printer f = Printexc.register_printer @@ function
| Effect.Unhandled (Yield elt) -> f (`Yield elt)
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Sequencer.run"
end
2 changes: 1 addition & 1 deletion src/Sequencer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ sig

The input type of the printer [p] is a variant representation of the internal effects used in this module. They correspond to the effects trigger by {!val:yield}. More precisely, [`Yield elt] corresponds to the effect triggered by [yield elt].

@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/State.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ struct
| Effect.Unhandled Get -> f `Get
| Effect.Unhandled (Set state) -> f (`Set state)
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.State.run"
end
2 changes: 1 addition & 1 deletion src/State.mli
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ sig
- [`Get] corresponds to the effect triggered by [get ()].
- [`Set state] corresponds to the effect triggered by [set state].

@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/UniqueID.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ struct
| Effect.Unhandled (Retrieve id) -> f (`Retrieve id)
| Effect.Unhandled Export -> f `Export
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.UniqueID.run"
end
2 changes: 1 addition & 1 deletion src/UniqueID.mli
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sig
- [`Retrieve id] corresponds to the effect triggered by [retrieve id].
- [`Export] corresponds to the effect triggered by [export ()].

@since 1.0.0
@since 1.1.0
*)
end

Expand Down
4 changes: 4 additions & 0 deletions src/Unmonad.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ struct
; exnc = raise
; effc = function Monadic m -> Option.some @@ fun k -> M.bind m (Effect.Deep.continue k) | _ -> None
}

let () = Printexc.register_printer @@ function
| Effect.Unhandled (Monadic _) -> Some "Unhandled algaeff effect; use Algaeff.Unmonad.run"
| _ -> None
end
5 changes: 3 additions & 2 deletions src/Unmonad.mli
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
(** Effects for any monad (subject to OCaml continuations being one-shot). *)

(** This is a general construction that uses effects to construct monadic expressions.
Here is an alternative implementation of {!module:State} using
the standard state monad:
Here is an alternative implementation of {!module:State} using the standard state monad:

{[
module StateMonad =
Expand Down Expand Up @@ -33,6 +32,8 @@
raise an exception unless it encounters a truly unrecoverable fatal error. Raising an exception
within [bind] will skip the continuation, and thus potentially skipping exception handlers
within the continuation. Those handlers might be crucial for properly releasing acquired resources.

PS: We are not aware of any actual use of this module, but we decided to keep it anyway.
*)

module type Monad =
Expand Down