I can understand the arguments of primitive types, which is demo-ed in the document.
let args () = Deriving.Args.(empty +> arg "option1" (eint __) +> flag "flag") ;;
However, I don’t try out how to set a value of some custom types (I have no e.g. eint
esting
to use).
type config = Config
type t = Foo [@@deriving my_ppx ~cfg:config]
I was searching for some ppx libraries but I don’t find examples using non-primitive types so even reading a few source code doesn’t help me to solve this problem. I have to pass the config in because it’s initialized by some other external library.
ppx_accessor has non-primitive arguments:
[@@deriving accessors ~submodule:My_submodule]
The implementation is at ppx_accessor/src/ppx_accessor.ml at 41b81cc45de5b5bb6ab13b393ef6269c31013157 · janestreet/ppx_accessor · GitHub.
More importantly, I found that through https://sherlocode.com/?q=Deriving.Args which may have a few more examples.
2 Likes
Sorry for being a bit late but I just found some time to try this problem.
The ppx_accessor
’s example, is actually reading a string ("My_submodule"
)
utop # Ast_pattern.lident;;
- : (string, 'a, 'b) Ast_pattern.t -> (longident, 'a, 'b) Ast_pattern.t = <fun>
let args () = Deriving.Args.(empty +> arg "submodule" (pexp_construct (lident __) none))
None of the examples in the search link on sherlocode that I have checked use custom types.
I tried reading the source code inside Ast_builder
and I wonder it may be infeasible to customize the argument if I cannot have config_from_string
. This code is copied out from ast_pattern.ml
and changed for running outside. Ignoring the code for continuation thing, the conversion is x |> int_of_string |> pconst_integer |> pexp_constant
.
let int' tf =
let f = Ast_pattern.to_func tf in
let f' ctx loc x k = f ctx loc (int_of_string x) k in
Ast_pattern.of_func f'
let const_int t = Ast_pattern.pconst_integer (int' t) Ast_pattern.none
let eint t = Ast_pattern.pexp_constant (const_int t)
I think I still have very vague understanding for Ast_pattern
(Do we have to use continuation to make it composable?).
The good side is I realized passing the config in may be a bad code idea. I can split heavy config away: let my ppx generate a functor and leave the user to make the real module.