Skip to content

Commit

Permalink
fix: break the functor Run into Run and TryWith
Browse files Browse the repository at this point in the history
  • Loading branch information
favonia committed Jul 30, 2022
1 parent 4737260 commit 59d622a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 13 deletions.
7 changes: 6 additions & 1 deletion src/Modifier.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ struct
| _ -> None

let run f = try_with f () {effc = handler}
let try_with = run
end

module TryWith (H : Handler) =
struct
module R = Run (H)
let try_with = R.run
end
end
10 changes: 7 additions & 3 deletions src/ModifierSigs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,21 @@ sig
sig
val run : (unit -> 'a) -> 'a
(** [run f h] initializes the engine and runs the thunk [f], using [h] to handle modifier effects. See {!module-type:Handler}. *)
end

module TryWith (H : Handler) :
sig
val try_with : (unit -> 'a) -> 'a
(** [try_with f h] runs the thunk [f], using [h] to handle the intercepted modifier effects. See {!module-type:Handler}.
Currently, [try_with] is an alias of {!val:run}, but [try_with] is intended to use within {!val:run} to intercept effects,
while {!val:run} is intended to be at the outermost layer to handle effects. That is, the following is the expected program structure:
Currently, [try_with] is an alias of {!val:Run.run}, but [try_with] is intended to use within {!val:Run.run} to intercept or reperform effects, while {!val:Run.run} is intended to be at the top-level to set up the environment and handle effects by itself. That is, the following is the expected program structure:
{[
run @@ fun () ->
(* code *)
try_with f
try_with @@ fun () ->
(* more code *)
try_with @@ fun () ->
(* even more code *)
]}
*)
end
Expand Down
3 changes: 2 additions & 1 deletion src/Scope.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ struct
module M = Mod.Run (H)
let run ?(export_prefix=Emp) ?(init_visible=Trie.empty) f =
M.run (fun () -> Internal.run ~export_prefix ~init_visible f)
let try_with = M.try_with
end

module TryWith (H : Handler) = Mod.TryWith (H)

module Perform = Mod.Perform
end
11 changes: 6 additions & 5 deletions src/ScopeSigs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ sig
originating from export namespaces. The default is the empty path ([Emp]).
This does not affect paths originating from visible namespaces.
@param init_visible The initial visible namespace. The default is the empty trie. *)
end

module TryWith (H : Handler) :
sig
val try_with : (unit -> 'a) -> 'a
(** Execute the code and handles the internal modifier effects. This can be used to intercept
or reperform those effects; for example, the following function silences the [shadow] effects.
See also {!val:Modifier.S.Run.try_with}.
(** Execute the code and handles the internal modifier effects. [try_with] is intended to use within {!val:Run.run} to intercept or reperform internal effects, while {!val:Run.run} is intended to be at the top-level to set up the environment and handle all effects by itself. For example, the following function silences the [shadow] effects. See also {!val:Modifier.S.TryWith.try_with}.
{[
module H =
Expand All @@ -113,10 +114,10 @@ sig
let shadow _ _ _ y = y
end
let silence_shadow f = let module R = Run (H) in R.try_with f
let silence_shadow f = let module R = TryWith (H) in R.try_with f
]}
Note that {!val:run} starts a fresh empty scope while [try_with] remains in the current scope.
Note that {!val:Run.run} starts a fresh empty scope while [try_with] remains in the current scope.
*)
end

Expand Down
6 changes: 3 additions & 3 deletions test/Example.ml
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ struct
input
end

module SilentH : S.Handler =
module SilenceShadow : S.Handler =
struct
include S.Perform
let shadow _ _ _ y = y
end

(* Mute the [shadow] effects. *)
let silence_shadow f =
let module R = S.Run (SilentH) in
R.try_with f
let module T = S.TryWith (SilenceShadow) in
T.try_with f

(* The interpreter *)
let rec interpret_decl : decl -> unit =
Expand Down

0 comments on commit 59d622a

Please sign in to comment.