pattern

Run-time patterns that explain match failures
README

pattern is a PPX extension that generates functions from
patterns that explain match failures by returning the common context
and the list of differences between a pattern and a value.

To quote the differences, the generated function needs a /quoter/ for
the value to be matched, that is to say a function of type 'a -> Parsetree.expression where 'a is the type of the matched value.
Such a quoter may be derived by using the ppxlib.traverse_lift
deriving plugin and the ppxlib.metaquot_lifters library.

type example = { x : int; y : int; z : int }
    [@@deriving traverse_lift]

let quoter = object
  inherit Ppxlib_metaquot_lifters.expression_lifters Location.none
  inherit [Parsetree.expression] lift
end

let () =
  let v = { x = 1; y = 2; z = 3 } in
  match [%pattern? { x = 1; y = 2; z = 4 }] ~quoted:(quoter#example v) v with
  | Ok () -> assert false
  | Error failure ->
      Format.printf "%a@." Pattern_runtime.format_failure failure;
      (* { x = _; y = _; z = (@0) }
         @0: Expected: 4
             Got: 3 *)
      begin
        match failure with
        | { common = [%pat?
              { x = _; y = _;
                z = [%p? { ppat_desc = Ppat_var { txt = "@0"; _ }; _}]}];
            mismatches = [{
              ident = "@0";
              expected = [%pat? 4];
              got = Some [%expr 3];
            }]} -> ()
        | _ -> assert false
      end

If patterns have binders, then in case of successful match, the
generated function returns Ok bindings, where bindings is an
object, with one constant method for each binder.

let () =
  let v = { x = 1; y = 2; z = 3 } in
  match [%pattern? { x; y; z }] ~quoted:(quoter#example v) v with
  | Ok binders ->
      assert (binders#x = 1);
      assert (binders#y = 2);
      assert (binders#z = 3)
  | Error failure ->
      Format.printf "%a@." Pattern_runtime.format_failure failure;
      assert false

Pattern_runtime.check can be used to match a value against a pattern
without having to repeat the value when calling the quoter. Since the
value argument is passed before the pattern, if the type of the value
is known during type inference, then it can be used to resolve the
variant constructor and the record field names that appear in the
pattern.

let () =
  let v = { x = 1; y = 2; z = 3 } in
  match Pattern_runtime.check quoter#example v [%pattern? { x; y; z }] with
  | Ok binders ->
      assert (binders#x = 1);
      assert (binders#y = 2);
      assert (binders#z = 3)
  | Error failure ->
      Format.printf "%a@." Pattern_runtime.format_failure failure;
      assert false
Install
Published
27 Sep 2019
Sources
pattern-0.1.1.tar.gz
sha512=5fa5bfba1a4f2587a391ec622ab4281d4a2acceaac2fdc45a85990cbc98e5c2865b6634363374ae7b554435f500f5a80065c1abc2b33698175a72a38a66f8724
Dependencies
stdcompat
>= "10"
ppxlib
>= "0.9.0" & < "0.14.0"
dune
>= "1.10.0"
Reverse Dependencies
clangml
= "4.0.1"