package yuujinchou

  1. Overview
  2. Docs

The signature of an engine.

module Param : sig ... end
module type Perform = sig ... end

The signature of a module implementing all effect handlers for a modifier engine.

module Perform : Perform

The handlers that (re-)perform effects.

module Silence : Perform

The handlers that silence effects. All the triggers actually do nothing.

type not_found_handler = Param.context option -> Trie.bwd_path -> unit

The type of a handler of the Modifier.S.Perform.not_found effect.

type shadow_handler = Param.context option -> Trie.bwd_path -> ( * Param.tag) -> ( * Param.tag) -> * Param.tag

The type of a handler of the Modifier.S.Perform.shadow effect.

The type of a handler of the Modifier.S.Perform.hook effect.

modify modifier trie runs the modifier on the trie and return the transformed trie.

  • parameter context

    The context sent to the effect handlers. If unspecified, effects come with None as their context.

  • parameter prefix

    The prefix prepended to any path or prefix sent to the effect handlers. The default is the empty path (Emp).

val run : ?not_found:not_found_handler -> ?shadow:shadow_handler -> ?hook:hook_handler -> (unit -> 'a) -> 'a

run f initializes the engine and runs the thunk f.

  • parameter not_found

    not_found ctx prefix is called when the engine expects at least one binding within the subtree at prefix but could not find any, where ctx is the context passed to modify. Modifiers such as Language.all, Language.only, Language.none, and a few other modifiers expect at least one matching binding. For example, the modifier Language.except ["x"; "y"] expects that there was already something under the subtree at x.y. If there were actually no names with the prefix x.y, then the modifier will trigger this effect with prefix being Emp #< "x" #< "y". The default handler directly returns the value (), effectively ignoring the warning.

  • parameter shadow

    shadow ctx path x y is called when item y is being assigned to path but x is already bound at path, where ctx is the context passed to modify. Modifiers created by Language.union could lead to multiple bindings having the same name, and when that happens, this function is called to resolve the conflicting bindings. The default handler directly returns the y (the later binding), effectively shadowing the earlier binding x silently.

  • parameter hook

    hook prefix id input is called when processing modifiers created by Language.hook, where ctx is the context passed to modify. When the engine encounters the modifier Language.hook id while handling the subtree input at prefix, it will call hook prefix id input and replace the existing subtree input with the return value. The default handler returns input, which is effectively a no-op.

val try_with : ?not_found:not_found_handler -> ?shadow:shadow_handler -> ?hook:hook_handler -> (unit -> 'a) -> 'a

try_with f runs the thunk f and intercepts modifier effects. See the documentation of run for the meaning of the optional effect interceptors; the difference is that the default interceptors reperform the intercepted modifier effects instead of silencing them.

try_with is intended to be used within run to intercept or reperform effects, while 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 ~not_found ~shadow ~hook @@ fun () ->
(* code *)
try_with ~not_found @@ fun () ->
(* more code *)
try_with ~shadow @@ fun () ->
(* even more code *)
val register_printer : ([ `NotFound of Param.context option * Trie.bwd_path | `Shadow of Param.context option * Trie.bwd_path * ( * Param.tag) * ( * Param.tag) | `Hook of Param.context option * Trie.bwd_path * Param.hook * (, Param.tag) Trie.t ] -> string option) -> unit

register_printer p registers a printer p via 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 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 Modifier.Make always registers a simple printer to suggest using 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 Printexc.register_printer and all the registered printers (via this function or Printexc.register_printer) are put into the same list.

The input type of the printer p is a variant representation of all internal effects used in this module. They correspond to the three effect triggers by the functions in Perform. More precisely,

  • `NotFound (ctx, prefix) corresponds to the effect triggered by Perform.not_found ctx prefix; and
  • `Shadow (ctx, path, x, y) corresponds to Perform.shadow ctx path x y; and
  • `Hook (ctx, prefix, id, input) corresponds to Perform.hook ctx prefix id input.

See also the documentation of run for a detailed explanation of these effects.

  • since 5.1.0

Innovation. Community. Security.