如何在相互递归类型中使用派生 Show()?
How to use deriving Show() in mutually recursive types?
直接看代码
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 to print info about the two types. According to its document,我只需要在要打印的类型后添加 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() 应该怎么办?感谢您的帮助!
要导出 pretty-printing 函数,您可以使用 ppx_deriving1。首先,确保你已经安装了它,
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 "%s\n%a@\n" (show_symbol input) pp_symbol input
我为您在问题中未提供的类型添加了一些别名。请注意,所有类型都必须指定 [@@deriving show]
。当一个类型是递归的时候,只需将 and
视为 type
。基本上,和你做的一样,但我们需要使用 ppx-syntax,例如 [@@deriving show]
而不是 Ocsigen 的
在程序的最后,有一个例子展示了如何使用生成的函数。有两种类型的函数,show_foo
将类型 foo
的值转换为字符串,pretty-printing 函数 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))
如果您正在使用其他构建系统,请不要犹豫,我们将需要有关您的构建系统的更多信息或 link 您的项目。如果您刚刚开始一个新项目并且不知道应该使用哪个构建系统,那么沙丘就是答案。
1)这不是唯一的选择。您还可以使用 ppx_jane 的 sexp 派生器 ppx_show,可能还有更多。
直接看代码
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 to print info about the two types. According to its document,我只需要在要打印的类型后添加 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() 应该怎么办?感谢您的帮助!
要导出 pretty-printing 函数,您可以使用 ppx_deriving1。首先,确保你已经安装了它,
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 "%s\n%a@\n" (show_symbol input) pp_symbol input
我为您在问题中未提供的类型添加了一些别名。请注意,所有类型都必须指定 [@@deriving show]
。当一个类型是递归的时候,只需将 and
视为 type
。基本上,和你做的一样,但我们需要使用 ppx-syntax,例如 [@@deriving show]
而不是 Ocsigen 的
在程序的最后,有一个例子展示了如何使用生成的函数。有两种类型的函数,show_foo
将类型 foo
的值转换为字符串,pretty-printing 函数 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))
如果您正在使用其他构建系统,请不要犹豫,我们将需要有关您的构建系统的更多信息或 link 您的项目。如果您刚刚开始一个新项目并且不知道应该使用哪个构建系统,那么沙丘就是答案。
1)这不是唯一的选择。您还可以使用 ppx_jane 的 sexp 派生器 ppx_show,可能还有更多。