Library
Module
Module type
Parameter
Class
Class type
The functor to generate a module for scoping effects.
include Param
with type data = P.data
with type tag = P.tag
with type hook = P.hook
with type context = P.context
type data = P.data
The type of data held by the bindings. The difference between data and tags is that the data will survive the efficient retagging. See Trie.retag
.
type tag = P.tag
The type of tags attached to the bindings. The difference between data and tags is that tags can be efficiently reset. See Trie.retag
.
type hook = P.hook
The type of modifier hook labels. This is for extending the modifier language.
type context = P.context
The type of contexts passed to each call of Modifier.S.modify
for the effect handler to distinguish different function calls.
The exception Locked
is raised when an operation on a scope starts before another operation on the same scope is finished. This could happen when the user, for example, calls modify_visible
and then calls modify_export
when handling the effects.
The principle is that one should not access any scope in its intermediate states, including looking up a name via resolve
. Any attempt to do so will raise the exception Locked
.
Note: section
only locks the parent scope; the child scope is initially unlocked.
resolve p
looks up the name p
in the current scope and return the data associated with the binding.
val include_singleton :
?context_visible:context ->
?context_export:context ->
(Trie.path * (data * tag)) ->
unit
include_singleton (p, x)
adds a new binding to both the visible and export namespaces, where the binding is associating the data x
to the path p
. Conflicting names during the final merge will trigger the effect shadow
.
val include_subtree :
?context_visible:context ->
?context_export:context ->
(Trie.path * (data, tag) Trie.t) ->
unit
include_subtree (p, ns)
merges the namespace ns
prefixed with p
into both the visible and export namespaces. Conflicting names during the final merge will trigger the effect shadow
.
include_subtree (p, ns)
merges the namespace ns
prefixed with p
into the visible namespace (while keeping the export namespace intact). Conflicting names during the final merge will trigger the effect Mod.Shadowing
.
val modify_visible : ?context:context -> hook Language.t -> unit
modify_visible m
modifies the visible namespace by running the modifier m
on it, using the internal modifier engine.
val modify_export : ?context:context -> hook Language.t -> unit
modify_visible m
modifies the export namespace by running the modifier m
on it, using the internal modifier engine.
val modify :
?context:context ->
?prefix:Trie.bwd_path ->
hook Language.t ->
(data, tag) Trie.t ->
(data, tag) Trie.t
Call the internal modifier engine directly on some trie. See Modifier.S.modify
.
This will not lock the current scope.
val export_visible : ?context:context -> hook Language.t -> unit
export_visible m
runs the modifier m
on the visible namespace, and then merge the result into the export namespace. Conflicting names during the final merge will trigger the effect Mod.Shadowing
.
get_export ()
returns the export namespace of the current scope.
val section :
?context_visible:context ->
?context_export:context ->
Trie.path ->
(unit -> 'a) ->
'a
section p f
starts a new scope and runs the thunk f
within the scope. The child scope inherits the visible namespace from the parent, and its export namespace will be prefixed with p
and merged into both the visible and export namespaces of the parent scope.
val run :
?export_prefix:Trie.bwd_path ->
?init_visible:(data, tag) Trie.t ->
(unit -> 'a) ->
(data, tag, hook, context) handler ->
'a
run f h
initializes a scope and executes the thunk f
, using h
to handle modifier effects.
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 Modifier.S.try_with
.
let silence_shadow f = try_with f {perform with shadow = fun _ _ _ y -> y}
Note that run
starts a fresh empty scope while try_with
remains in the current scope.