我们直接看代码。
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)
我想使用包派生来打印关于这两种类型的信息。根据它的文档,我只需要在我想打印的类型后面加上deriving (Show)
。但是我不能通过像这样添加and
来定义相互递归类型:
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)
编译上面的代码会得到下面的错误:
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
如果我想在相互递归类型上使用派生Show(),我该怎么做?谢谢你的帮助!
可以使用ppx_derived1派生出漂亮的打印函数。首先,确保你已经安装了
opam install ppx_deriving
接下来,让我们基于您的输入创建一个示例项目,
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 "%sn%a@n" (show_symbol input) pp_symbol input
我为你的问题中没有提供的类型添加了一些别名。注意,所有类型都必须指定[@@deriving show]
。当类型是递归时,只需将and
视为type
。基本上,和你做的一样,但是我们需要使用ppx语法,例如,[@@deriving show]
,而不是Ocsigen的。
在程序的最后,有一个示例显示了如何使用生成的函数。有两种类型的函数,show_foo
将foo
类型的值转换为字符串,而美观打印函数pp_foo
将foo
打印到格式化程序中,由于不需要创建中间字符串,因此速度更快。打印机与%a
说明符一起使用,并接受两个参数,打印机本身和要打印的值。所以不需要加括号,这也是一个小胜利。我在示例中使用了这两个选项,以便您可以对它们进行对比。
最后,如何构建它?如果您使用的是dune
,那么下面是dune
示例文件
(executable
(name example)
(preprocess
(pps ppx_deriving.show)))
您可以自己创建dune
文件或使用以下命令(假设我们的程序在example.ml
文件中),
dune init executable example --ppx=ppx_deriving.show
你可以用
dune exec ./example.exe
如果你使用ocamlbuild
而不是dune,那么只需将-package ppx_deriving.show
添加到ocamlbuild
调用中,例如
ocamlbuild -package ppx_deriving.show example.native
./example.native
都将打印
(Example.StarDes (Example.Const 1))
(Example.StarDes (Example.Const 1))
如果您正在使用其他构建系统,请不要犹豫,我们将需要更多关于您的构建系统的信息或项目链接。如果你刚开始一个新项目,不知道应该使用哪个构建系统,那么dune就是答案。
1)这不是唯一的选择。您还可以使用ppx_jane的sexp派生程序ppx_show,可能还有更多。