Types OCaml绑定具有嵌套类型的变量

Types OCaml绑定具有嵌套类型的变量,types,nested,ocaml,Types,Nested,Ocaml,我是OCaml新手,正在尝试跳入一个大型OCaml项目。在跟踪构成其他类型的类型时,我试图思考如何使用这些类型,因此我将其分解为一个小示例,我认为这个示例与大型项目中的情况非常接近 如果记录类型表达式由三个字段组成: type expression = {e_id:int; e_node:exp_node; e_loc:location} and exp_node = | Const of int | Lval of lval | SizeofStr of string and lv

我是OCaml新手,正在尝试跳入一个大型OCaml项目。在跟踪构成其他类型的类型时,我试图思考如何使用这些类型,因此我将其分解为一个小示例,我认为这个示例与大型项目中的情况非常接近

如果记录类型
表达式
由三个字段组成:

type expression = {e_id:int; e_node:exp_node; e_loc:location}
and exp_node =
  | Const of int
  | Lval of lval
  | SizeofStr of string
and lval =
  | Var of varinfo
  | Mem of expression
and location = {x:int; y:int}
and varinfo = {vname:string; vorigname:string}
如果
e_节点
字段是整数,我可以绑定这种类型的变量:

let exp_const = {e_id=10;
                 e_node= Const 10;
                 e_loc={x=10; y=10}}
现在,如果我想让
e_节点
字段属于
Lval
类型,即记录类型
Lval
,我想不出怎么做。我试过:

let exp_lval_var =
  {e_id=11;
   e_node= {vname="int_val"; vorigname="int_val1"};
   e_loc={x=10; y=20}}
但它表示,
此表达式的类型为varinfo,但表达式的类型应为exp\u node
。但是如果你按照类型,它是


我在这里没有正确定义类型吗?还是我没有正确使用这些类型?我找不到更多更复杂的使用OCaml类型的例子。这里的任何建议都将不胜感激。

就像您编写的
Const 10
(而不仅仅是
10
),您需要编写
Lval(Var{…})
来为
e_节点
字段获取正确的值

let exp_lval_var =
  {e_id=11;
   e_node= Lval (Var {vname="int_val"; vorigname="int_val1"});
   e_loc={x=10; y=20}}
要遵循第一个示例的类型,请执行以下操作:

  • 10
    的类型为
    int
  • Const 10
    属于
    exp\u节点类型
第二个例子

  • {vname=“int_val”vorigname=“int_val1”}
    属于
    varinfo类型
  • Var{vname=“int_val”vorigname=“int_val1”}
    属于
    lval类型
  • Lval(Var{vname=“int_val”vorigname=“int_val1”)属于
    exp_节点类型

Const
Var
Lval
这样的值构造函数不仅仅是OCaml中文档的标签。它们必须作为表达式的一部分出现,才能为其类型生成值。

谢谢!这很有意义,然后使用我的
exp\u lval\u var
如果我有它,并且想要访问与之相关的
vname
,我想要一个函数来获取它?如果我遍历类型以获取
vname
记录元素,比如在
Printf.Printf“%s”
的参数中,这样做就不是很符合Ocaml习惯了?(我意识到副作用也不是真正的习惯用法,因为它们是副作用)这样的函数是否是最好的选择:让get_vname{e_id=u;e_node=node;e_loc=}=match node with | Const I->Printf.sprintf“e_node is int:%I(无vname)“I|Lval lv->(将lv与{Var{vname=vstring;vorigname=vostring匹配)->Printf.sprintf“%s到%s”vostring vstring | Mem->“have expression”)| SizeofStr sizestr->Printf.sprintf“e”节点是SizeofStr:%s(无vname)“sizestr”,然后我可以像
Printf.Printf“%s”(get_vname exp_lval_var)一样使用它
实际上,对于
Mem