Let's directly see the codes.
type symbol =
| JumpDes of int
| CallDes of func
| StarDes of exp (*here needs the definition of type exp*)
deriving (Show)
type exp =
| Const of const
| Symbol of symbol (*here needs the definition of type symbol*)
| Reg of reg
| Assist of assistop
| Ptr of ptraddr
| Label of string
deriving (Show)
I'd like to use package deriving to print info about the two types. According to its document, i just need to add deriving (Show)
after types i want to print. But i can not define mutually recursive types by adding and
like this:
type symbol =
| JumpDes of int
| CallDes of func
| StarDes of exp
deriving (Show)
and exp = (*note that it's line 240*)
| Const of const
| Symbol of symbol
| Reg of reg
| Assist of assistop
| Ptr of ptraddr
| Label of string
deriving (Show)
Compiling codes above will get error below:
File "type.ml", line 240, characters 16-17:
Parse error: [semi] expected after [str_item] (in [implem])
File "type.ml", line 1:
Error: Error while running external preprocessor
How should i do if i'd like to use deriving Show() on mutually recursive types? Thanks for your help!
To derive pretty-printing functions you can use ppx_deriving1. First of all, make sure that you have it installed,
opam install ppx_deriving
Next, let's create a sample project based on your input,
type func = string [@@deriving show]
type const = int [@@deriving show]
type reg = int [@@deriving show]
type assistop = int [@@deriving show]
type ptraddr = int [@@deriving show]
type symbol =
| JumpDes of int
| CallDes of func
| StarDes of exp
[@@deriving show]
and exp =
| Const of const
| Symbol of symbol
| Reg of reg
| Assist of assistop
| Ptr of ptraddr
| Label of string
[@@deriving show]
let () =
let input = StarDes (Const 1) in
Format.printf "%s\n%a@\n" (show_symbol input) pp_symbol input
I put some aliases for the types that you didn't provide in your question. Notice that all the types had to specify [@@deriving show]
. When a type is recursive, just treat and
as type
. Basically, the same as you did, but we need to use the ppx-syntax, e.g., [@@deriving show]
not the Ocsigen one.
At the end of the program, there is an example that shows how to use the generated functions. There are two types of function, show_foo
which translates a value of type foo
into the string, and the pretty-printing function pp_foo
that prints foo
into the formatter, which is faster since there is no need to create an intermediate string. The printers are used with the %a
specifier and take two arguments, the printer itself and the value to print. So there's no need to put parentheses, also a small win. I used both options in the example, so that you can contrast them.
Finally, how to build it? If you're using dune
, then here's the sample dune
file,
(executable
(name example)
(preprocess
(pps ppx_deriving.show)))
You can create the dune
file yourself or use the following command (assuming that our program is in the example.ml
file),
dune init executable example --ppx=ppx_deriving.show
You can run example with,
dune exec ./example.exe
If you're using ocamlbuild
instead of dune, then just add -package ppx_deriving.show
to your ocamlbuild
invocation, e.g.,
ocamlbuild -package ppx_deriving.show example.native
./example.native
Both will print,
(Example.StarDes (Example.Const 1))
(Example.StarDes (Example.Const 1))
If you're using some other build system, then don't hesitate to ask, we will need more information about your build system or a link to your project. If you just starting a new project and don't know which build system you should use, then dune is the answer.
1)This is not the only option. You can also use ppx_jane's sexp deriver, ppx_show, and probably there are a few more.