Reputation: 422
I'm trying to define notation for a type I defined in my OCaml project. Basically this type allows me to express either one or two values of a type and I called it maybe_pair
. I'd like to be able to write some notation for defining values of this type, for example:
<5> : int maybe_pair
<3;7> : int maybe_pair
I'm basically trying to imitate how the lists notation work, but I believe this may be impossible.
Upvotes: 1
Views: 201
Reputation: 73
You can write a ppx-rewriter to partially achieve your goal, although the notation with angle brackes isn't supported.
I'll assume the pair is defined as follows:
(* file: pair.ml *)
type 'a maybe_pair = MkPair of 'a * 'a option [@@deriving show]
The ppx extension should then look as follows:
(* file: ppx_pair.ml *)
open Ppxlib
let name = "mp"
let expand ~loc ~path:_ expr =
match expr with
| {pexp_desc = Pexp_sequence (e1,e2); _} -> [%expr Pair.MkPair ([%e e1], Some [%e e2]) ]
| e1 -> [%expr Pair.MkPair ([%e e1], None) ]
let ext =
Extension.declare name Extension.Context.expression
Ast_pattern.(single_expr_payload __)
expand
let () = Driver.register_transformation name ~extensions:[ext]
We can see it in action as follows:
let () =
let x = [%mp 1] in
Format.printf "x is %a\n" (Pair.pp_maybe_pair Format.pp_print_int) x;
let x = [%mp 1; 2] in
Format.printf "x is %a\n" (Pair.pp_maybe_pair Format.pp_print_int) x
Outputs:
x is (Pair.MkPair (1, None))
x is (Pair.MkPair (1, (Some 2)))
I've made a minimally working example project structure here: https://gitlab.com/gopiandcode/example-ppxlib
Upvotes: 0
Reputation: 66803
You can't get the notation you want just by defining OCaml functions. You can define <
and >
as infix operators (with a fixed pre-defined precedence), but you can't define them to work in pairs like parentheses.
You can get any desired syntax using the OCaml syntax extension mechanism ppx. But this is a large subject, too big for an answer here on StackOverflow (in my opinion).
You can read about PPX here: https://ocamlverse.github.io/content/ppx.html
And here: https://github.com/ocaml-ppx/ppxlib
Upvotes: 1
Reputation: 1246
The type below can hold either one or two values of type 'a
:
type 'a maybe_pair = Single of 'a | Double of 'a * 'a
Upvotes: 0